- u.u_error = copyin((caddr_t)uap->iovp, (caddr_t)aiov,
- uap->iovcnt * sizeof (struct iovec));
- if (u.u_error)
- return;
- rwuio(&auio, UIO_READ);
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_USERSPACE;
+ if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov,
+ uap->iovcnt * sizeof (struct iovec)))
+ goto done;
+ auio.uio_resid = 0;
+ for (i = 0; i < uap->iovcnt; i++) {
+ if (iov->iov_len < 0) {
+ error = EINVAL;
+ goto done;
+ }
+ auio.uio_resid += iov->iov_len;
+ if (auio.uio_resid < 0) {
+ error = EINVAL;
+ goto done;
+ }
+ iov++;
+ }
+#ifdef KTRACE
+ /*
+ * if tracing, save a copy of iovec
+ */
+ if (KTRPOINT(u.u_procp, KTR_GENIO)) {
+ int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
+
+ 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 (setjmp(&u.u_qsave)) {
+ if (auio.uio_resid == cnt) {
+ if ((u.u_sigintr & sigmask(u.u_procp->p_cursig)) != 0)
+ error = EINTR;
+ else
+ u.u_eosys = RESTARTSYS;
+ }
+ } else
+ error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
+ cnt -= auio.uio_resid;
+#ifdef KTRACE
+ if (ktriov != NULL) {
+ ktrgenio(u.u_procp->p_tracep, uap->fdes, UIO_READ, ktriov, cnt);
+ FREE(ktriov, M_TEMP);
+ }
+#endif
+ u.u_r.r_val1 = cnt;
+done:
+ if (uap->iovcnt > UIO_SMALLIOV)
+ FREE(iov, M_IOV);
+ RETURN (error);