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/2c8951c0f2c0
branches:  trunk
changeset: 832410:2c8951c0f2c0
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 41d4104b7f6e -r 2c8951c0f2c0 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 41d4104b7f6e -r 2c8951c0f2c0 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 41d4104b7f6e -r 2c8951c0f2c0 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 41d4104b7f6e -r 2c8951c0f2c0 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