+ msg.msg_iov = aiov;
+ if (msg.msg_accrights)
+ if (useracc((caddr_t)msg.msg_accrights,
+ (unsigned)msg.msg_accrightslen, B_WRITE) == 0) {
+ u.u_error = EFAULT;
+ return;
+ }
+ recvit(uap->s, &msg, uap->flags,
+ (caddr_t)&uap->msg->msg_namelen,
+ (caddr_t)&uap->msg->msg_accrightslen);
+}
+
+recvit(s, mp, flags, namelenp, rightslenp)
+ int s;
+ register struct msghdr *mp;
+ int flags;
+ caddr_t namelenp, rightslenp;
+{
+ register struct file *fp;
+ struct uio auio;
+ register struct iovec *iov;
+ register int i;
+ struct mbuf *from, *rights;
+ int len;
+
+ fp = getsock(s);
+ if (fp == 0)
+ return;
+ auio.uio_iov = mp->msg_iov;
+ auio.uio_iovcnt = mp->msg_iovlen;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_offset = 0; /* XXX */
+ auio.uio_resid = 0;
+ iov = mp->msg_iov;
+ for (i = 0; i < mp->msg_iovlen; i++, iov++) {
+ if (iov->iov_len < 0) {
+ u.u_error = EINVAL;
+ return;
+ }
+ if (iov->iov_len == 0)
+ continue;
+ if (useracc(iov->iov_base, (u_int)iov->iov_len, B_WRITE) == 0) {
+ u.u_error = EFAULT;
+ return;
+ }
+ auio.uio_resid += iov->iov_len;
+ }
+ len = auio.uio_resid;
+ u.u_error =
+ soreceive((struct socket *)fp->f_data, &from, &auio,
+ flags, &rights);
+ u.u_r.r_val1 = len - auio.uio_resid;
+ if (mp->msg_name) {
+ len = mp->msg_namelen;
+ if (len <= 0 || from == 0)
+ len = 0;
+ else {
+ if (len > from->m_len)
+ len = from->m_len;
+ (void) copyout((caddr_t)mtod(from, caddr_t),
+ (caddr_t)mp->msg_name, (unsigned)len);
+ }
+ (void) copyout((caddr_t)&len, namelenp, sizeof (int));
+ }
+ if (mp->msg_accrights) {
+ len = mp->msg_accrightslen;
+ if (len <= 0 || rights == 0)
+ len = 0;
+ else {
+ if (len > rights->m_len)
+ len = rights->m_len;
+ (void) copyout((caddr_t)mtod(rights, caddr_t),
+ (caddr_t)mp->msg_accrights, (unsigned)len);
+ }
+ (void) copyout((caddr_t)&len, rightslenp, sizeof (int));