+ struct uio auio;
+ register struct iovec *iov;
+ register int i;
+ struct mbuf *to, *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_READ) == 0) {
+ u.u_error = EFAULT;
+ return;
+ }
+ auio.uio_resid += iov->iov_len;
+ }
+ if (mp->msg_name) {
+ u.u_error =
+ sockargs(&to, mp->msg_name, mp->msg_namelen, MT_SONAME);
+ if (u.u_error)
+ return;
+ } else
+ to = 0;
+ if (mp->msg_accrights) {
+ u.u_error =
+ sockargs(&rights, mp->msg_accrights, mp->msg_accrightslen,
+ MT_RIGHTS);
+ if (u.u_error)
+ goto bad;
+ } else
+ rights = 0;
+ len = auio.uio_resid;
+ u.u_error =
+ sosend((struct socket *)fp->f_data, to, &auio, flags, rights);
+ u.u_r.r_val1 = len - auio.uio_resid;
+ if (rights)
+ m_freem(rights);
+bad:
+ if (to)
+ m_freem(to);
+}
+
+recvfrom()
+{
+ register struct a {
+ int s;
+ caddr_t buf;
+ int len;
+ int flags;
+ caddr_t from;
+ int *fromlenaddr;
+ } *uap = (struct a *)u.u_ap;
+ struct msghdr msg;
+ struct iovec aiov;
+ int len;
+
+ u.u_error = copyin((caddr_t)uap->fromlenaddr, (caddr_t)&len,
+ sizeof (len));
+ if (u.u_error)
+ return;
+ msg.msg_name = uap->from;
+ msg.msg_namelen = len;
+ msg.msg_iov = &aiov;
+ msg.msg_iovlen = 1;
+ aiov.iov_base = uap->buf;
+ aiov.iov_len = uap->len;
+ msg.msg_accrights = 0;
+ msg.msg_accrightslen = 0;
+ recvit(uap->s, &msg, uap->flags, (caddr_t)uap->fromlenaddr, (caddr_t)0);
+}
+
+recv()
+{
+ register struct a {
+ int s;
+ caddr_t buf;
+ int len;
+ int flags;
+ } *uap = (struct a *)u.u_ap;
+ struct msghdr msg;
+ struct iovec aiov;
+
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &aiov;
+ msg.msg_iovlen = 1;
+ aiov.iov_base = uap->buf;
+ aiov.iov_len = uap->len;
+ msg.msg_accrights = 0;
+ msg.msg_accrightslen = 0;
+ recvit(uap->s, &msg, uap->flags, (caddr_t)0, (caddr_t)0);
+}
+
+recvmsg()
+{
+ register struct a {
+ int s;
+ struct msghdr *msg;
+ int flags;
+ } *uap = (struct a *)u.u_ap;
+ struct msghdr msg;
+ struct iovec aiov[MSG_MAXIOVLEN];
+
+ u.u_error = copyin((caddr_t)uap->msg, (caddr_t)&msg, sizeof (msg));
+ if (u.u_error)
+ return;
+ if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0])) {
+ u.u_error = EMSGSIZE;
+ return;
+ }
+ u.u_error =
+ copyin((caddr_t)msg.msg_iov, (caddr_t)aiov,
+ (unsigned)(msg.msg_iovlen * sizeof (aiov[0])));
+ if (u.u_error)
+ return;
+ 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);
+}