Index: emulation/linux/linux_file.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/linux/linux_file.c,v retrieving revision 1.10 diff -u -u -r1.10 linux_file.c --- emulation/linux/linux_file.c 15 Oct 2003 06:38:46 -0000 1.10 +++ emulation/linux/linux_file.c 15 Oct 2003 08:04:04 -0000 @@ -743,34 +743,46 @@ int linux_pread(struct linux_pread_args *uap) { - struct pread_args bsd; + struct thread *td = curthread; + struct uio auio; + struct iovec aiov; int error; - bsd.fd = uap->fd; - bsd.buf = uap->buf; - bsd.nbyte = uap->nbyte; - bsd.offset = uap->offset; - bsd.sysmsg_result = 0; + aiov.iov_base = uap->buf; + aiov.iov_len = uap->nbyte; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = uap->offset; + auio.uio_resid = uap->nbyte; + auio.uio_rw = UIO_READ; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_td = td; + + error = kern_readv(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); - error = pread(&bsd); - uap->sysmsg_result = bsd.sysmsg_result; return(error); } int linux_pwrite(struct linux_pwrite_args *uap) { - struct pwrite_args bsd; + struct thread *td = curthread; + struct uio auio; + struct iovec aiov; int error; - bsd.fd = uap->fd; - bsd.buf = uap->buf; - bsd.nbyte = uap->nbyte; - bsd.offset = uap->offset; - bsd.sysmsg_result = 0; + aiov.iov_base = uap->buf; + aiov.iov_len = uap->nbyte; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = uap->offset; + auio.uio_resid = uap->nbyte; + auio.uio_rw = UIO_WRITE; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_td = td; + + error = kern_writev(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); - error = pwrite(&bsd); - uap->sysmsg_result = bsd.sysmsg_result; return(error); } Index: kern/sys_generic.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/sys_generic.c,v retrieving revision 1.13 diff -u -u -r1.13 sys_generic.c --- kern/sys_generic.c 11 Oct 2003 19:04:58 -0000 1.13 +++ kern/sys_generic.c 15 Oct 2003 08:13:43 -0000 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -76,10 +77,6 @@ static int pollscan (struct proc *, struct pollfd *, u_int, int *); static int selscan (struct proc *, fd_mask **, fd_mask **, int, int *); -static int dofileread (struct file *, int, void *, - size_t, off_t, int, int *); -static int dofilewrite (struct file *, int, - const void *, size_t, off_t, int, int *); struct file* holdfp(fdp, fd, flag) @@ -104,16 +101,22 @@ read(struct read_args *uap) { struct thread *td = curthread; - struct proc *p = td->td_proc; - struct file *fp; + struct uio auio; + struct iovec aiov; int error; - KKASSERT(p); - if ((fp = holdfp(p->p_fd, uap->fd, FREAD)) == NULL) - return (EBADF); - error = dofileread(fp, uap->fd, uap->buf, uap->nbyte, (off_t)-1, 0, - &uap->sysmsg_result); - fdrop(fp, td); + aiov.iov_base = uap->buf; + aiov.iov_len = uap->nbyte; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = -1; + auio.uio_resid = uap->nbyte; + auio.uio_rw = UIO_READ; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_td = td; + + error = kern_readv(uap->fd, &auio, 0, &uap->sysmsg_result); + return(error); } @@ -124,170 +127,109 @@ pread(struct pread_args *uap) { struct thread *td = curthread; - struct proc *p = td->td_proc; - struct file *fp; + struct uio auio; + struct iovec aiov; int error; - KKASSERT(p); - if ((fp = holdfp(p->p_fd, uap->fd, FREAD)) == NULL) - return (EBADF); - if (fp->f_type != DTYPE_VNODE) { - error = ESPIPE; - } else { - error = dofileread(fp, uap->fd, uap->buf, uap->nbyte, - uap->offset, FOF_OFFSET, &uap->sysmsg_result); - } - fdrop(fp, td); + aiov.iov_base = uap->buf; + aiov.iov_len = uap->nbyte; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = uap->offset; + auio.uio_resid = uap->nbyte; + auio.uio_rw = UIO_READ; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_td = td; + + error = kern_readv(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); + return(error); } -/* - * Code common for read and pread - */ int -dofileread(fp, fd, buf, nbyte, offset, flags, res) - struct file *fp; - int fd, flags; - void *buf; - size_t nbyte; - off_t offset; - int *res; +readv(struct readv_args *uap) { struct thread *td = curthread; struct uio auio; - struct iovec aiov; - long cnt, error = 0; -#ifdef KTRACE - struct iovec ktriov; - struct proc *p = td->td_proc; - struct uio ktruio; - int didktr = 0; -#endif + struct iovec aiov[UIO_SMALLIOV], *iov = NULL; + int error; - aiov.iov_base = (caddr_t)buf; - aiov.iov_len = nbyte; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_offset = offset; - if (nbyte > INT_MAX) - return (EINVAL); - auio.uio_resid = nbyte; + error = iovec_copyin(uap->iovp, &iov, aiov, uap->iovcnt, + &auio.uio_resid); + if (error) + return (error); + auio.uio_iov = iov; + auio.uio_iovcnt = uap->iovcnt; + auio.uio_offset = -1; auio.uio_rw = UIO_READ; auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; -#ifdef KTRACE - /* - * if tracing, save a copy of iovec - */ - if (KTRPOINT(td, KTR_GENIO)) { - ktriov = aiov; - ktruio = auio; - didktr = 1; - } -#endif - cnt = nbyte; - if ((error = fo_read(fp, &auio, fp->f_cred, flags, td))) { - if (auio.uio_resid != cnt && (error == ERESTART || - error == EINTR || error == EWOULDBLOCK)) - error = 0; - } - cnt -= auio.uio_resid; -#ifdef KTRACE - if (didktr && error == 0) { - ktruio.uio_iov = &ktriov; - ktruio.uio_resid = cnt; - ktrgenio(p->p_tracep, fd, UIO_READ, &ktruio, error); - } -#endif - *res = cnt; + error = kern_readv(uap->fd, &auio, 0, &uap->sysmsg_result); + + iovec_free(&iov, aiov); return (error); } -/* - * Scatter read system call. - */ int -readv(struct readv_args *uap) +kern_readv(int fd, struct uio *auio, int flags, int *res) { struct thread *td = curthread; struct proc *p = td->td_proc; struct file *fp; struct filedesc *fdp = p->p_fd; - struct uio auio; - struct iovec *iov; - struct iovec *needfree = NULL; - struct iovec aiov[UIO_SMALLIOV]; - long i, cnt, error = 0; - u_int iovlen; + int len, error; #ifdef KTRACE struct iovec *ktriov = NULL; struct uio ktruio; #endif - if ((fp = holdfp(fdp, uap->fd, FREAD)) == NULL) + KKASSERT(p); + + fp = holdfp(fdp, fd, FREAD); + if (fp == NULL) return (EBADF); - /* note: can't use iovlen until iovcnt is validated */ - iovlen = uap->iovcnt * sizeof (struct iovec); - if (uap->iovcnt > UIO_SMALLIOV) { - if (uap->iovcnt > UIO_MAXIOV) { - error = EINVAL; - goto done; - } - MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); - needfree = iov; - } else - iov = aiov; - auio.uio_iov = iov; - auio.uio_iovcnt = uap->iovcnt; - auio.uio_rw = UIO_READ; - auio.uio_segflg = UIO_USERSPACE; - auio.uio_td = td; - auio.uio_offset = -1; - if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) + if (flags & FOF_OFFSET && fp->f_type != DTYPE_VNODE) { + error = ESPIPE; + goto done; + } + if (auio->uio_resid < 0) { + error = EINVAL; goto done; - auio.uio_resid = 0; - for (i = 0; i < uap->iovcnt; i++) { - if (iov->iov_len > INT_MAX - 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(td, 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); - ktruio = auio; + bcopy((caddr_t)auio->uio_iov, (caddr_t)ktriov, iovlen); + ktruio = *auio; } #endif - cnt = auio.uio_resid; - if ((error = fo_read(fp, &auio, fp->f_cred, 0, td))) { - if (auio.uio_resid != cnt && (error == ERESTART || + len = auio->uio_resid; + error = fo_read(fp, auio, fp->f_cred, flags, td); + if (error) { + if (auio->uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; } - cnt -= auio.uio_resid; #ifdef KTRACE if (ktriov != NULL) { if (error == 0) { ktruio.uio_iov = ktriov; - ktruio.uio_resid = cnt; - ktrgenio(p->p_tracep, uap->fd, UIO_READ, &ktruio, - error); + ktruio.uio_resid = len - auio->uio_resid; + ktrgenio(p->p_tracep, fd, UIO_READ, &ktruio, error); } FREE(ktriov, M_TEMP); } #endif - uap->sysmsg_result = cnt; + if (error == 0) + *res = len - auio->uio_resid; done: fdrop(fp, td); - if (needfree) - FREE(needfree, M_IOV); return (error); } @@ -298,17 +240,22 @@ write(struct write_args *uap) { struct thread *td = curthread; - struct proc *p = td->td_proc; - struct file *fp; + struct uio auio; + struct iovec aiov; int error; - KKASSERT(p); + aiov.iov_base = (void *)(uintptr_t)uap->buf; + aiov.iov_len = uap->nbyte; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = -1; + auio.uio_resid = uap->nbyte; + auio.uio_rw = UIO_WRITE; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_td = td; + + error = kern_writev(uap->fd, &auio, 0, &uap->sysmsg_result); - if ((fp = holdfp(p->p_fd, uap->fd, FWRITE)) == NULL) - return (EBADF); - error = dofilewrite(fp, uap->fd, uap->buf, uap->nbyte, (off_t)-1, 0, - &uap->sysmsg_result); - fdrop(fp, td); return(error); } @@ -319,84 +266,47 @@ pwrite(struct pwrite_args *uap) { struct thread *td = curthread; - struct proc *p = td->td_proc; - struct file *fp; + struct uio auio; + struct iovec aiov; int error; - KKASSERT(p); - if ((fp = holdfp(p->p_fd, uap->fd, FWRITE)) == NULL) - return (EBADF); - if (fp->f_type != DTYPE_VNODE) { - error = ESPIPE; - } else { - error = dofilewrite(fp, uap->fd, uap->buf, uap->nbyte, - uap->offset, FOF_OFFSET, &uap->sysmsg_result); - } - fdrop(fp, td); + aiov.iov_base = (void *)(uintptr_t)uap->buf; + aiov.iov_len = uap->nbyte; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = uap->offset; + auio.uio_resid = uap->nbyte; + auio.uio_rw = UIO_WRITE; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_td = td; + + error = kern_writev(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); + return(error); } -static int -dofilewrite( - struct file *fp, - int fd, - const void *buf, - size_t nbyte, - off_t offset, - int flags, - int *res -) { +int +writev(struct writev_args *uap) +{ struct thread *td = curthread; - struct proc *p = td->td_proc; struct uio auio; - struct iovec aiov; - long cnt, error = 0; -#ifdef KTRACE - struct iovec ktriov; - struct uio ktruio; - int didktr = 0; -#endif + struct iovec aiov[UIO_SMALLIOV], *iov = NULL; + int error; - aiov.iov_base = (void *)(uintptr_t)buf; - aiov.iov_len = nbyte; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_offset = offset; - if (nbyte > INT_MAX) - return (EINVAL); - auio.uio_resid = nbyte; + error = iovec_copyin(uap->iovp, &iov, aiov, uap->iovcnt, + &auio.uio_resid); + if (error) + return (error); + auio.uio_iov = iov; + auio.uio_iovcnt = uap->iovcnt; + auio.uio_offset = -1; auio.uio_rw = UIO_WRITE; auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; -#ifdef KTRACE - /* - * if tracing, save a copy of iovec and uio - */ - if (KTRPOINT(td, KTR_GENIO)) { - ktriov = aiov; - ktruio = auio; - didktr = 1; - } -#endif - cnt = nbyte; - if (fp->f_type == DTYPE_VNODE) - bwillwrite(); - if ((error = fo_write(fp, &auio, fp->f_cred, flags, td))) { - if (auio.uio_resid != cnt && (error == ERESTART || - error == EINTR || error == EWOULDBLOCK)) - error = 0; - if (error == EPIPE) - psignal(p, SIGPIPE); - } - cnt -= auio.uio_resid; -#ifdef KTRACE - if (didktr && error == 0) { - ktruio.uio_iov = &ktriov; - ktruio.uio_resid = cnt; - ktrgenio(p->p_tracep, fd, UIO_WRITE, &ktruio, error); - } -#endif - *res = cnt; + + error = kern_writev(uap->fd, &auio, 0, &uap->sysmsg_result); + + iovec_free(&iov, aiov); return (error); } @@ -404,96 +314,68 @@ * Gather write system call */ int -writev(struct writev_args *uap) +kern_writev(int fd, struct uio *auio, int flags, int *res) { struct thread *td = curthread; struct proc *p = td->td_proc; struct file *fp; - struct filedesc *fdp; - struct uio auio; - struct iovec *iov; - struct iovec *needfree; - struct iovec aiov[UIO_SMALLIOV]; - long i, cnt, error = 0; - u_int iovlen; + struct filedesc *fdp = p->p_fd; + long len, error; #ifdef KTRACE struct iovec *ktriov = NULL; struct uio ktruio; #endif KKASSERT(p); - fdp = p->p_fd; - if ((fp = holdfp(fdp, uap->fd, FWRITE)) == NULL) + fp = holdfp(fdp, fd, FWRITE); + if (fp == NULL) return (EBADF); - /* note: can't use iovlen until iovcnt is validated */ - iovlen = uap->iovcnt * sizeof (struct iovec); - if (uap->iovcnt > UIO_SMALLIOV) { - if (uap->iovcnt > UIO_MAXIOV) { - needfree = NULL; - error = EINVAL; - goto done; - } - MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); - needfree = iov; - } else { - iov = aiov; - needfree = NULL; + if (flags & FOF_OFFSET && fp->f_type != DTYPE_VNODE) { + error = ESPIPE; + goto done; } - auio.uio_iov = iov; - auio.uio_iovcnt = uap->iovcnt; - auio.uio_rw = UIO_WRITE; - auio.uio_segflg = UIO_USERSPACE; - auio.uio_td = td; - auio.uio_offset = -1; - if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) + if (auio->uio_resid < 0) { + error = EINVAL; goto done; - auio.uio_resid = 0; - for (i = 0; i < uap->iovcnt; i++) { - if (iov->iov_len > INT_MAX - auio.uio_resid) { - error = EINVAL; - goto done; - } - auio.uio_resid += iov->iov_len; - iov++; } #ifdef KTRACE /* * if tracing, save a copy of iovec and uio */ if (KTRPOINT(td, 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); - ktruio = auio; + bcopy((caddr_t)auio->uio_iov, (caddr_t)ktriov, iovlen); + ktruio = *auio; } #endif - cnt = auio.uio_resid; + len = auio->uio_resid; if (fp->f_type == DTYPE_VNODE) bwillwrite(); - if ((error = fo_write(fp, &auio, fp->f_cred, 0, td))) { - if (auio.uio_resid != cnt && (error == ERESTART || + error = fo_write(fp, auio, fp->f_cred, 0, td); + if (error) { + if (auio->uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; if (error == EPIPE) psignal(p, SIGPIPE); } - cnt -= auio.uio_resid; #ifdef KTRACE if (ktriov != NULL) { if (error == 0) { ktruio.uio_iov = ktriov; - ktruio.uio_resid = cnt; - ktrgenio(p->p_tracep, uap->fd, UIO_WRITE, &ktruio, - error); + ktruio.uio_resid = len - auio->uio_resid; + ktrgenio(p->p_tracep, fd, UIO_WRITE, &ktruio, error); } FREE(ktriov, M_TEMP); } #endif - uap->sysmsg_result = cnt; + if (error == 0) + *res = len - auio->uio_resid; done: fdrop(fp, td); - if (needfree) - FREE(needfree, M_IOV); return (error); } Index: sys/kern_syscall.h =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/kern_syscall.h,v retrieving revision 1.6 diff -u -u -r1.6 kern_syscall.h --- sys/kern_syscall.h 15 Oct 2003 06:38:46 -0000 1.6 +++ sys/kern_syscall.h 15 Oct 2003 07:01:09 -0000 @@ -31,26 +31,32 @@ #ifndef _SYS_KERN_SYSCALL_H_ #define _SYS_KERN_SYSCALL_H_ -/* - * Prototypes for syscalls in kern/kern_descrip.c - */ enum dup_type {DUP_FIXED, DUP_VARIABLE}; union fcntl_dat; - -int kern_dup(enum dup_type type, int old, int new, int *res); -int kern_fcntl(int fd, int cmd, union fcntl_dat *dat); - -/* - * Prototypes for syscalls in kern/uipc_syscalls.c - */ struct mbuf; struct msghdr; struct sf_hdtr; struct sockaddr; struct socket; struct sockopt; +struct uio; struct vnode; +/* + * Prototypes for syscalls in kern/kern_descrip.c + */ +int kern_dup(enum dup_type type, int old, int new, int *res); +int kern_fcntl(int fd, int cmd, union fcntl_dat *dat); + +/* + * Prototypes for syscalls in kern/sys_generic.c + */ +int kern_readv(int fd, struct uio *auio, int flags, int *res); +int kern_writev(int fd, struct uio *auio, int flags, int *res); + +/* + * Prototypes for syscalls in kern/uipc_syscalls.c + */ int kern_accept(int s, struct sockaddr **name, int *namelen, int *res); int kern_bind(int s, struct sockaddr *sa); int kern_connect(int s, struct sockaddr *sa);