once. libc, man page, and regress parts to come.
With input from jca@, bluhm@.
OK bluhm@
-/* $OpenBSD: init_sysent.c,v 1.245 2022/09/02 13:23:33 mbuhl Exp $ */
+/* $OpenBSD: init_sysent.c,v 1.246 2022/09/03 12:33:44 mbuhl Exp $ */
/*
* System call switch table.
sys___realpath }, /* 115 = __realpath */
{ 5, s(struct sys_recvmmsg_args), SY_NOLOCK | 0,
sys_recvmmsg }, /* 116 = recvmmsg */
- { 0, 0, 0,
- sys_nosys }, /* 117 = unimplemented sendmmsg */
+ { 4, s(struct sys_sendmmsg_args), SY_NOLOCK | 0,
+ sys_sendmmsg }, /* 117 = sendmmsg */
{ 5, s(struct sys_getsockopt_args), 0,
sys_getsockopt }, /* 118 = getsockopt */
{ 3, s(struct sys_thrkill_args), 0,
-/* $OpenBSD: syscalls.c,v 1.243 2022/09/02 13:23:33 mbuhl Exp $ */
+/* $OpenBSD: syscalls.c,v 1.244 2022/09/03 12:33:44 mbuhl Exp $ */
/*
* System call names.
"unveil", /* 114 = unveil */
"__realpath", /* 115 = __realpath */
"recvmmsg", /* 116 = recvmmsg */
- "#117 (unimplemented sendmmsg)", /* 117 = unimplemented sendmmsg */
+ "sendmmsg", /* 117 = sendmmsg */
"getsockopt", /* 118 = getsockopt */
"thrkill", /* 119 = thrkill */
"readv", /* 120 = readv */
-; $OpenBSD: syscalls.master,v 1.230 2022/09/02 13:18:06 mbuhl Exp $
+; $OpenBSD: syscalls.master,v 1.231 2022/09/03 12:33:44 mbuhl Exp $
; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
116 STD NOLOCK { int sys_recvmmsg(int s, struct mmsghdr *mmsg, \
unsigned int vlen, unsigned int flags, \
struct timespec *timeout); }
-117 UNIMPL sendmmsg
+117 STD NOLOCK { int sys_sendmmsg(int s, \
+ struct mmsghdr *mmsg, unsigned int vlen, \
+ unsigned int flags); }
118 STD { int sys_getsockopt(int s, int level, int name, \
void *val, socklen_t *avalsize); }
119 STD { int sys_thrkill(pid_t tid, int signum, void *tcb); }
-/* $OpenBSD: uipc_syscalls.c,v 1.202 2022/09/02 13:18:06 mbuhl Exp $ */
+/* $OpenBSD: uipc_syscalls.c,v 1.203 2022/09/03 12:33:44 mbuhl Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
/*
return (error);
}
+int
+sys_sendmmsg(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_sendmmsg_args /* {
+ syscallarg(int) s;
+ syscallarg(struct mmsghdr *) mmsg;
+ syscallarg(unsigned int) vlen;
+ syscallarg(unsigned int) flags;
+ } */ *uap = v;
+ struct mmsghdr mmsg, *mmsgp;
+ struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *uiov;
+ size_t iovlen = UIO_SMALLIOV;
+ register_t retsnd;
+ unsigned int vlen, dgrams;
+ int error = 0;
+
+ /* Arbitrarily capped at 1024 datagrams. */
+ vlen = SCARG(uap, vlen);
+ if (vlen > 1024)
+ vlen = 1024;
+
+ mmsgp = SCARG(uap, mmsg);
+ for (dgrams = 0; dgrams < vlen; dgrams++) {
+ error = copyin(&mmsgp[dgrams], &mmsg, sizeof(mmsg));
+ if (error)
+ break;
+
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_STRUCT))
+ ktrmmsghdr(p, &mmsg);
+#endif
+
+ if (mmsg.msg_hdr.msg_iovlen > IOV_MAX) {
+ error = EMSGSIZE;
+ break;
+ }
+
+ if (mmsg.msg_hdr.msg_iovlen > iovlen) {
+ if (iov != aiov)
+ free(iov, M_IOV, iovlen *
+ sizeof(struct iovec));
+
+ iovlen = mmsg.msg_hdr.msg_iovlen;
+ iov = mallocarray(iovlen, sizeof(struct iovec),
+ M_IOV, M_WAITOK);
+ }
+
+ if (mmsg.msg_hdr.msg_iovlen > 0) {
+ error = copyin(mmsg.msg_hdr.msg_iov, iov,
+ mmsg.msg_hdr.msg_iovlen * sizeof(struct iovec));
+ if (error)
+ break;
+ }
+
+#ifdef KTRACE
+ if (mmsg.msg_hdr.msg_iovlen && KTRPOINT(p, KTR_STRUCT))
+ ktriovec(p, iov, mmsg.msg_hdr.msg_iovlen);
+#endif
+
+ uiov = mmsg.msg_hdr.msg_iov;
+ mmsg.msg_hdr.msg_iov = iov;
+ mmsg.msg_hdr.msg_flags = 0;
+
+ error = sendit(p, SCARG(uap, s), &mmsg.msg_hdr,
+ SCARG(uap, flags), &retsnd);
+ if (error)
+ break;
+
+ mmsg.msg_hdr.msg_iov = uiov;
+ mmsg.msg_len = retsnd;
+
+ error = copyout(&mmsg, &mmsgp[dgrams], sizeof(mmsg));
+ if (error)
+ break;
+ }
+
+ if (iov != aiov)
+ free(iov, M_IOV, sizeof(struct iovec) * iovlen);
+
+ *retval = dgrams;
+
+ if (dgrams)
+ return 0;
+ return error;
+}
+
int
sendit(struct proc *p, int s, struct msghdr *mp, int flags, register_t *retsize)
{
-/* $OpenBSD: socket.h,v 1.103 2022/09/02 13:18:07 mbuhl Exp $ */
+/* $OpenBSD: socket.h,v 1.104 2022/09/03 12:33:45 mbuhl Exp $ */
/* $NetBSD: socket.h,v 1.14 1996/02/09 18:25:36 christos Exp $ */
/*
ssize_t sendto(int, const void *,
size_t, int, const struct sockaddr *, socklen_t);
ssize_t sendmsg(int, const struct msghdr *, int);
+int sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int);
int setsockopt(int, int, int, const void *, socklen_t);
int shutdown(int, int);
int sockatmark(int);
-/* $OpenBSD: syscall.h,v 1.242 2022/09/02 13:23:33 mbuhl Exp $ */
+/* $OpenBSD: syscall.h,v 1.243 2022/09/03 12:33:45 mbuhl Exp $ */
/*
* System call numbers.
/* syscall: "recvmmsg" ret: "int" args: "int" "struct mmsghdr *" "unsigned int" "unsigned int" "struct timespec *" */
#define SYS_recvmmsg 116
+/* syscall: "sendmmsg" ret: "int" args: "int" "struct mmsghdr *" "unsigned int" "unsigned int" */
+#define SYS_sendmmsg 117
+
/* syscall: "getsockopt" ret: "int" args: "int" "int" "int" "void *" "socklen_t *" */
#define SYS_getsockopt 118
-/* $OpenBSD: syscallargs.h,v 1.245 2022/09/02 13:23:33 mbuhl Exp $ */
+/* $OpenBSD: syscallargs.h,v 1.246 2022/09/03 12:33:45 mbuhl Exp $ */
/*
* System call argument lists.
syscallarg(struct timespec *) timeout;
};
+struct sys_sendmmsg_args {
+ syscallarg(int) s;
+ syscallarg(struct mmsghdr *) mmsg;
+ syscallarg(unsigned int) vlen;
+ syscallarg(unsigned int) flags;
+};
+
struct sys_getsockopt_args {
syscallarg(int) s;
syscallarg(int) level;
int sys_unveil(struct proc *, void *, register_t *);
int sys___realpath(struct proc *, void *, register_t *);
int sys_recvmmsg(struct proc *, void *, register_t *);
+int sys_sendmmsg(struct proc *, void *, register_t *);
int sys_getsockopt(struct proc *, void *, register_t *);
int sys_thrkill(struct proc *, void *, register_t *);
int sys_readv(struct proc *, void *, register_t *);