- RETURN (error);
- if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0]))
- RETURN (EMSGSIZE);
- msg.msg_flags = uap->flags;
- if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)aiov,
- (unsigned)(msg.msg_iovlen * sizeof (aiov[0]))))
- RETURN (error);
- msg.msg_iov = aiov;
- if (msg.msg_control && useracc((caddr_t)msg.msg_control,
- (unsigned)msg.msg_controllen, B_WRITE) == 0)
- RETURN (EFAULT);
-
- RETURN (recvit(uap->s, &msg, (caddr_t)&uap->msg->msg_namelen,
- (caddr_t)&uap->msg->msg_accrightslen, /* compat_43 */1));
+ return (error);
+ if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
+ if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
+ return (EMSGSIZE);
+ MALLOC(iov, struct iovec *,
+ sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
+ M_WAITOK);
+ } else
+ iov = aiov;
+ msg.msg_flags = uap->flags | MSG_COMPAT;
+ if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
+ (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
+ goto done;
+ msg.msg_iov = iov;
+ error = recvit(p, uap->s, &msg, (caddr_t)&uap->msg->msg_namelen, retval);
+
+ if (msg.msg_controllen && error == 0)
+ error = copyout((caddr_t)&msg.msg_controllen,
+ (caddr_t)&uap->msg->msg_accrightslen, sizeof (int));
+done:
+ if (iov != aiov)
+ FREE(iov, M_IOV);
+ return (error);