- auio.uio_iov = aiov;
- auio.uio_iovcnt = uap->iovcnt;
- u.u_error = copyin((caddr_t)uap->iovp, (caddr_t)aiov,
- (unsigned)(uap->iovcnt * sizeof (struct iovec)));
- if (u.u_error)
- return;
- rwuio(&auio, UIO_READ);
+ auio.uio_iov = iov;
+ auio.uio_iovcnt = SCARG(uap, iovcnt);
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_procp = p;
+ if (error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen))
+ goto done;
+ auio.uio_resid = 0;
+ for (i = 0; i < SCARG(uap, iovcnt); i++) {
+ if (auio.uio_resid + iov->iov_len < auio.uio_resid) {
+ error = EINVAL;
+ goto done;
+ }
+ auio.uio_resid += iov->iov_len;
+ iov++;
+ }
+#ifdef KTRACE
+ /*
+ * if tracing, save a copy of iovec
+ */
+ if (KTRPOINT(p, KTR_GENIO)) {
+ MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
+ bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
+ }
+#endif
+ cnt = auio.uio_resid;
+ if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))
+ if (auio.uio_resid != cnt && (error == ERESTART ||
+ error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ cnt -= auio.uio_resid;
+#ifdef KTRACE
+ if (ktriov != NULL) {
+ if (error == 0)
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, ktriov,
+ cnt, error);
+ FREE(ktriov, M_TEMP);
+ }
+#endif
+ *retval = cnt;
+done:
+ if (needfree)
+ FREE(needfree, M_IOV);
+ return (error);