--- //depot/projects/smpng/sys/compat/freebsd32/freebsd32_misc.c 2005/07/13 18:25:40 +++ //depot/user/jhb/proc/compat/freebsd32/freebsd32_misc.c 2005/09/20 18:54:39 @@ -796,7 +796,116 @@ return (error); } +static int +freebsd32_copyiniov(struct iovec32 *iovp, u_int iovcnt, struct iovec **iov, + int error) +{ + struct iovec32 iov32; + int i; + + u_int iovlen; + + *iov = NULL; + if (iovcnt > UIO_MAXIOV) + return (error); + iovlen = iovcnt * sizeof(struct iovec); + *iov = malloc(iovlen, M_IOV, M_WAITOK); + for (i = 0; i < iovcnt; i++) { + error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); + if (error) { + free(*iov, M_IOV); + *iov = NULL; + return (error); + } + iov[i].iov_base = PTRIN(iov32.iov_base); + iov[i].iov_len = iov32.iov_len; + } + return (0); +} + +struct msghdr32 { + u_int32_t msg_name; + socklen_t msg_namelen; + u_int32_t msg_iov; + int msg_iovlen; + u_int32_t msg_control; + socklen_t msg_controllen; + int msg_flags; +}; +CTASSERT(sizeof(struct msghdr32) == 28); + +static int +freebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg) +{ + struct msghdr32 m32; + int error; + + error = copyin(msg32, &m32, sizeof(m32)); + if (error) + return (error); + msg->msg_name = PTRIN(m32.msg_name); + msg->msg_namelen = m32.msg_namelen; + msg->msg_iov = PTRIN(m32.msg_iov); + msg->msg_iovlen = m32.msg_iovlen; + msg->msg_control = PTRIN(m32.msg_control); + msg->msg_controllen = m32.msg_controllen; + msg->msg_flags = m32.msg_flags; + return (0); + return (freebsd32_copyiniov(m32.msg_iov, m32.msg_iovlen, &msg->msg_iov, + EMSGSIZE)); +} + +static int +freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32) +{ + struct msghdr32 m32; + + m32.msg_name = PTROUT(msg->msg_name); + m32.msg_namelen = msg->msg_namelen; + m32.msg_iov = PTROUT(msg->msg_iov); + m32.msg_iovlen = msg->msg_iovlen; + m32.msg_control = PTROUT(msg->msg_control); + m32.msg_controllen = msg->msg_controllen; + m32.msg_flags = msg->msg_flags; + error = copyout(msg32, &m32, sizeof(m32)); + if (error) + return (error); +} + int +freebsd32_recvmsg(td, uap) + struct thread *td; + struct freebsd32_recvmsg_args /* { + int s; + struct msghdr32 *msg; + int flags; + } */ *uap; +{ + struct msghdr msg32; + struct msghdr msg; + struct iovec *uiov, *iov; + int error; + + error = freebsd32_copyinmsghdr(uap->msg, &msg); + if (error) + return (error); + error = freebsd32_copyiniov((struct iovec32 *)msg->msg_iov, + msg->msg_iovlen, &iov, EMSGSIZE); + if (error) + return (error); + msg.msg_flags = uap->flags; + uiov = msg.msg_iov; + msg.msg_iov = iov; + error = kern_recvit(td, uap->s, &msg, NULL, UIO_SYSSPACE); + if (error == 0) { + msg.msg_iov = uiov; + error = freebsd32_copyoutmsghdr(&msg, uap->msg); + } + free(iov, M_IOV); + return (error); +} + +int freebsd32_settimeofday(struct thread *td, struct freebsd32_settimeofday_args *uap) { --- //depot/projects/smpng/sys/compat/freebsd32/syscalls.master 2005/07/13 20:43:18 +++ //depot/user/jhb/proc/compat/freebsd32/syscalls.master 2005/09/20 18:34:57 @@ -88,7 +88,8 @@ 26 AUE_NULL MNOPROTO { int ptrace(int req, pid_t pid, \ caddr_t addr, int data); } ; XXX implement -27 AUE_NULL UNIMPL recvmsg +27 AUE_NULL MSTD { int freebsd32_recvmsg(int s, struct msghdr32 *msg, \ + int flags); } 28 AUE_NULL MNOPROTO { int sendmsg(int s, caddr_t msg, \ int flags); } 29 AUE_NULL MNOPROTO { int recvfrom(int s, caddr_t buf, \ --- //depot/projects/smpng/sys/kern/uipc_syscalls.c 2005/07/07 19:45:15 +++ //depot/user/jhb/proc/kern/uipc_syscalls.c 2005/09/20 18:54:39 @@ -922,12 +922,13 @@ return (error); } -static int -recvit(td, s, mp, namelenp) +int +kern_recvit(td, s, mp, namelenp, segflg) struct thread *td; int s; struct msghdr *mp; void *namelenp; + enum uio_seg segflg; { struct uio auio; struct iovec *iov; @@ -964,7 +965,7 @@ auio.uio_iov = mp->msg_iov; auio.uio_iovcnt = mp->msg_iovlen; - auio.uio_segflg = UIO_USERSPACE; + auio.uio_segflg = segflg; auio.uio_rw = UIO_READ; auio.uio_td = td; auio.uio_offset = 0; /* XXX */ @@ -1082,6 +1083,17 @@ return (error); } +static int +recvit(td, s, mp, namelenp) + struct thread *td; + int s; + struct msghdr *mp; + void *namelenp; +{ + + return (kern_recvit(td, s, mp, namelenp, UIO_USERSPACE)); +} + /* * MPSAFE */ --- //depot/projects/smpng/sys/sys/syscallsubr.h 2005/07/07 19:45:15 +++ //depot/user/jhb/proc/sys/syscallsubr.h 2005/09/20 18:54:39 @@ -105,6 +105,8 @@ int kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, int count); int kern_readv(struct thread *td, int fd, struct uio *auio); +int kern_recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp, + enum uio_seg segflg); int kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg); int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg);