Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/compat/netbsd32 add {send,recv}mmsg
details: https://anonhg.NetBSD.org/src/rev/80f587056ceb
branches: trunk
changeset: 318948:80f587056ceb
user: christos <christos%NetBSD.org@localhost>
date: Thu May 10 02:36:07 2018 +0000
description:
add {send,recv}mmsg
diffstat:
sys/compat/netbsd32/netbsd32.h | 8 +-
sys/compat/netbsd32/netbsd32_compat_20.c | 5 +-
sys/compat/netbsd32/netbsd32_conv.h | 18 +-
sys/compat/netbsd32/netbsd32_socket.c | 375 ++++++++++++++++++++++++------
sys/compat/netbsd32/syscalls.master | 18 +-
5 files changed, 335 insertions(+), 89 deletions(-)
diffs (truncated from 561 to 300 lines):
diff -r dac39e235d8b -r 80f587056ceb sys/compat/netbsd32/netbsd32.h
--- a/sys/compat/netbsd32/netbsd32.h Thu May 10 01:32:24 2018 +0000
+++ b/sys/compat/netbsd32/netbsd32.h Thu May 10 02:36:07 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32.h,v 1.117 2018/04/14 04:04:39 mrg Exp $ */
+/* $NetBSD: netbsd32.h,v 1.118 2018/05/10 02:36:07 christos Exp $ */
/*
* Copyright (c) 1998, 2001, 2008, 2015 Matthew R. Green
@@ -715,6 +715,12 @@
int msg_accrightslen;
};
+typedef netbsd32_pointer_t netbsd32_mmsghdrp_t;
+struct netbsd32_mmsghdr {
+ struct netbsd32_msghdr msg_hdr;
+ unsigned int msg_len;
+};
+
/* from <sys/stat.h> */
typedef netbsd32_pointer_t netbsd32_stat12p_t;
struct netbsd32_stat12 { /* NetBSD-1.2 stat struct */
diff -r dac39e235d8b -r 80f587056ceb sys/compat/netbsd32/netbsd32_compat_20.c
--- a/sys/compat/netbsd32/netbsd32_compat_20.c Thu May 10 01:32:24 2018 +0000
+++ b/sys/compat/netbsd32/netbsd32_compat_20.c Thu May 10 02:36:07 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_compat_20.c,v 1.36 2017/04/13 09:46:59 hannken Exp $ */
+/* $NetBSD: netbsd32_compat_20.c,v 1.37 2018/05/10 02:36:07 christos Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_20.c,v 1.36 2017/04/13 09:46:59 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_20.c,v 1.37 2018/05/10 02:36:07 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -36,6 +36,7 @@
#include <sys/time.h>
#include <sys/ktrace.h>
#include <sys/vnode.h>
+#include <sys/socket.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/namei.h>
diff -r dac39e235d8b -r 80f587056ceb sys/compat/netbsd32/netbsd32_conv.h
--- a/sys/compat/netbsd32/netbsd32_conv.h Thu May 10 01:32:24 2018 +0000
+++ b/sys/compat/netbsd32/netbsd32_conv.h Thu May 10 02:36:07 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_conv.h,v 1.34 2018/04/19 21:50:08 christos Exp $ */
+/* $NetBSD: netbsd32_conv.h,v 1.35 2018/05/10 02:36:07 christos Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@@ -289,6 +289,22 @@
}
static __inline void
+netbsd32_to_mmsghdr(const struct netbsd32_mmsghdr *mmsg32,
+ struct mmsghdr *mmsg)
+{
+ netbsd32_to_msghdr(&mmsg32->msg_hdr, &mmsg->msg_hdr);
+ mmsg->msg_len = mmsg32->msg_len;
+}
+
+static __inline void
+netbsd32_from_mmsghdr(struct netbsd32_mmsghdr *mmsg32,
+ const struct mmsghdr *mmsg)
+{
+ netbsd32_from_msghdr(&mmsg32->msg_hdr, &mmsg->msg_hdr);
+ mmsg32->msg_len = mmsg->msg_len;
+}
+
+static __inline void
netbsd32_from_statvfs(const struct statvfs *sbp, struct netbsd32_statvfs *sb32p)
{
sb32p->f_flag = sbp->f_flag;
diff -r dac39e235d8b -r 80f587056ceb sys/compat/netbsd32/netbsd32_socket.c
--- a/sys/compat/netbsd32/netbsd32_socket.c Thu May 10 01:32:24 2018 +0000
+++ b/sys/compat/netbsd32/netbsd32_socket.c Thu May 10 02:36:07 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_socket.c,v 1.45 2018/05/03 21:43:33 christos Exp $ */
+/* $NetBSD: netbsd32_socket.c,v 1.46 2018/05/10 02:36:07 christos Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.45 2018/05/03 21:43:33 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.46 2018/05/10 02:36:07 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -159,6 +159,62 @@
return error;
}
+static int
+msg_recv_copyin(struct lwp *l, const struct netbsd32_msghdr *msg32,
+ struct msghdr *msg, struct iovec *aiov)
+{
+ int error;
+ size_t iovsz;
+ struct iovec *iov = aiov;
+
+ iovsz = msg32->msg_iovlen * sizeof(struct iovec);
+ if (msg32->msg_iovlen > UIO_SMALLIOV) {
+ if (msg32->msg_iovlen > IOV_MAX)
+ return EMSGSIZE;
+ iov = kmem_alloc(iovsz, KM_SLEEP);
+ }
+
+ error = netbsd32_to_iovecin(NETBSD32PTR64(msg32->msg_iov), iov,
+ msg32->msg_iovlen);
+ if (error)
+ goto out;
+
+ netbsd32_to_msghdr(msg32, msg);
+ msg->msg_iov = iov;
+out:
+ if (iov != aiov)
+ kmem_free(iov, iovsz);
+ return error;
+}
+
+static int
+msg_recv_copyout(struct lwp *l, struct netbsd32_msghdr *msg32,
+ struct msghdr *msg, struct netbsd32_msghdr *arg,
+ struct mbuf *from, struct mbuf *control)
+{
+ int error = 0;
+
+ if (msg->msg_control != NULL)
+ error = copyout32_msg_control(l, msg, control);
+
+ if (error == 0)
+ error = copyout_sockname(msg->msg_name, &msg->msg_namelen, 0,
+ from);
+
+ if (from != NULL)
+ m_free(from);
+ if (error)
+ return error;
+
+ msg32->msg_namelen = msg->msg_namelen;
+ msg32->msg_controllen = msg->msg_controllen;
+ msg32->msg_flags = msg->msg_flags;
+ ktrkuser("msghdr", msg, sizeof(*msg));
+ if (arg == NULL)
+ return 0;
+ return copyout(msg32, arg, sizeof(*arg));
+}
+
int
netbsd32_recvmsg(struct lwp *l, const struct netbsd32_recvmsg_args *uap,
register_t *retval)
@@ -169,61 +225,144 @@
syscallarg(int) flags;
} */
struct netbsd32_msghdr msg32;
- struct iovec aiov[UIO_SMALLIOV], *iov;
+ struct iovec aiov[UIO_SMALLIOV];
struct msghdr msg;
int error;
struct mbuf *from, *control;
- size_t iovsz;
error = copyin(SCARG_P32(uap, msg), &msg32, sizeof(msg32));
if (error)
return (error);
- iovsz = msg32.msg_iovlen * sizeof(struct iovec);
- if (msg32.msg_iovlen > UIO_SMALLIOV) {
- if (msg32.msg_iovlen > IOV_MAX)
- return (EMSGSIZE);
- iov = kmem_alloc(iovsz, KM_SLEEP);
- } else
- iov = aiov;
- error = netbsd32_to_iovecin(NETBSD32PTR64(msg32.msg_iov), iov,
- msg32.msg_iovlen);
- if (error)
- goto done;
+ if ((error = msg_recv_copyin(l, &msg32, &msg, aiov)) != 0)
+ return error;
msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
- msg.msg_name = NETBSD32PTR64(msg32.msg_name);
- msg.msg_namelen = msg32.msg_namelen;
- msg.msg_control = NETBSD32PTR64(msg32.msg_control);
- msg.msg_controllen = msg32.msg_controllen;
- msg.msg_iov = iov;
- msg.msg_iovlen = msg32.msg_iovlen;
-
error = do_sys_recvmsg(l, SCARG(uap, s), &msg,
&from, msg.msg_control != NULL ? &control : NULL, retval);
if (error != 0)
- goto done;
+ goto out;
+
+ error = msg_recv_copyout(l, &msg32, &msg, SCARG_P32(uap, msg),
+ from, control);
+out:
+ if (msg.msg_iov != aiov)
+ kmem_free(msg.msg_iov, msg.msg_iovlen * sizeof(struct iovec));
+ return error;
+}
+
+int
+netbsd32_recvmmsg(struct lwp *l, const struct netbsd32_recvmmsg_args *uap,
+ register_t *retval)
+{
+ /* {
+ syscallarg(int) s;
+ syscallarg(netbsd32_mmsghdr_t) mmsg;
+ syscallarg(unsigned int) vlen;
+ syscallarg(unsigned int) flags;
+ syscallarg(netbsd32_timespecp_t) timeout;
+ } */
+ struct mmsghdr mmsg;
+ struct netbsd32_mmsghdr mmsg32, *mmsg32p = SCARG_P32(uap, mmsg);
+ struct netbsd32_msghdr *msg32 = &mmsg32.msg_hdr;
+ struct socket *so;
+ struct msghdr *msg = &mmsg.msg_hdr;
+ int error, s;
+ struct mbuf *from, *control;
+ struct timespec ts, now;
+ struct netbsd32_timespec ts32;
+ unsigned int vlen, flags, dg;
+ struct iovec aiov[UIO_SMALLIOV];
+
+ ts.tv_sec = 0; // XXX: gcc
+ ts.tv_nsec = 0;
+ if (SCARG_P32(uap, timeout)) {
+ if ((error = copyin(SCARG_P32(uap, timeout), &ts32,
+ sizeof(ts32))) != 0)
+ return error;
+ getnanotime(&now);
+ netbsd32_to_timespec(&ts32, &ts);
+ timespecadd(&now, &ts, &ts);
+ }
+
+ s = SCARG(uap, s);
+ if ((error = fd_getsock(s, &so)) != 0)
+ return error;
+
+ vlen = SCARG(uap, vlen);
+ if (vlen > 1024)
+ vlen = 1024;
- if (msg.msg_control != NULL)
- error = copyout32_msg_control(l, &msg, control);
+ from = NULL;
+ flags = SCARG(uap, flags) & MSG_USERFLAGS;
+
+ for (dg = 0; dg < vlen;) {
+ error = copyin(mmsg32p + dg, &mmsg32, sizeof(mmsg32));
+ if (error)
+ break;
+
+ if ((error = msg_recv_copyin(l, msg32, msg, aiov)) != 0)
+ return error;
+
+ msg->msg_flags = flags & ~MSG_WAITFORONE;
+
+ if (from != NULL) {
+ m_free(from);
+ from = NULL;
+ }
- if (error == 0)
- error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0,
- from);
+ error = do_sys_recvmsg_so(l, s, so, msg, &from,
+ msg->msg_control != NULL ? &control : NULL, retval);
+ if (error) {
+ if (error == EAGAIN && dg > 0)
+ error = 0;
+ break;
+ }
+ error = msg_recv_copyout(l, msg32, msg, NULL,
+ from, control);
+ from = NULL;
+ if (error)
+ break;
+
+ mmsg32.msg_len = *retval;
+
+ error = copyout(&mmsg32, mmsg32p + dg, sizeof(mmsg32));
+ if (error)
+ break;
+
+ dg++;
+ if (msg->msg_flags & MSG_OOB)
+ break;
+
Home |
Main Index |
Thread Index |
Old Index