diff options
-rw-r--r-- | lib/libc/sys/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libc/sys/read.2 | 33 | ||||
-rw-r--r-- | lib/libc/sys/write.2 | 27 | ||||
-rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 28 | ||||
-rw-r--r-- | sys/compat/freebsd32/syscalls.master | 11 | ||||
-rw-r--r-- | sys/kern/sys_generic.c | 365 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 7 | ||||
-rw-r--r-- | sys/sys/syscallsubr.h | 2 | ||||
-rw-r--r-- | sys/sys/uio.h | 7 |
9 files changed, 297 insertions, 187 deletions
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 64836b9..53ac26b 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -127,7 +127,7 @@ MLINKS+=mlockall.2 munlockall.2 MLINKS+=modnext.2 modfnext.2 MLINKS+=mount.2 nmount.2 mount.2 unmount.2 MLINKS+=pathconf.2 fpathconf.2 -MLINKS+=read.2 pread.2 read.2 readv.2 +MLINKS+=read.2 pread.2 read.2 readv.2 read.2 preadv.2 MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2 MLINKS+=send.2 sendmsg.2 send.2 sendto.2 MLINKS+=setpgid.2 setpgrp.2 @@ -141,7 +141,7 @@ MLINKS+=swapon.2 swapoff.2 MLINKS+=truncate.2 ftruncate.2 MLINKS+=utimes.2 futimes.2 utimes.2 lutimes.2 MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2 -MLINKS+=write.2 pwrite.2 write.2 writev.2 +MLINKS+=write.2 pwrite.2 write.2 writev.2 write.2 pwritev.2 .if !defined(NO_P1003_1B) MLINKS+=sched_get_priority_max.2 sched_get_priority_min.2 \ sched_get_priority_max.2 sched_rr_get_interval.2 diff --git a/lib/libc/sys/read.2 b/lib/libc/sys/read.2 index 8dd7731..fb452e9 100644 --- a/lib/libc/sys/read.2 +++ b/lib/libc/sys/read.2 @@ -38,7 +38,8 @@ .Sh NAME .Nm read , .Nm readv , -.Nm pread +.Nm pread , +.Nm preadv .Nd read input .Sh LIBRARY .Lb libc @@ -49,9 +50,11 @@ .Ft ssize_t .Fn read "int d" "void *buf" "size_t nbytes" .Ft ssize_t +.Fn pread "int d" "void *buf" "size_t nbytes" "off_t offset" +.Ft ssize_t .Fn readv "int d" "const struct iovec *iov" "int iovcnt" .Ft ssize_t -.Fn pread "int d" "void *buf" "size_t nbytes" "off_t offset" +.Fn preadv "int d" "const struct iovec *iov" "int iovcnt" "off_t offset" .Sh DESCRIPTION The .Fn read @@ -73,12 +76,16 @@ buffers specified by the members of the array: iov[0], iov[1], ..., iov[iovcnt\|\-\|1]. The .Fn pread -system call -performs the same function, but reads from the specified position in +and +.Fn preadv +system calls +perform the same functions, but read from the specified position in the file without modifying the file pointer. .Pp For -.Fn readv , +.Fn readv +and +.Fn preadv , the .Fa iovec structure is defined as: @@ -119,8 +126,9 @@ object is undefined. Upon successful completion, .Fn read , .Fn readv , -and .Fn pread +and +.Fn preadv return the number of bytes actually read and placed in the buffer. The system guarantees to read the number of bytes requested if the descriptor references a normal file that has that many bytes left @@ -137,8 +145,9 @@ is set to indicate the error. The .Fn read , .Fn readv , -and .Fn pread +and +.Fn preadv system calls will succeed unless: .Bl -tag -width Er @@ -189,6 +198,8 @@ is greater than .Pp In addition, .Fn readv +and +.Fn preadv may return one of the following errors: .Bl -tag -width Er .It Bq Er EINVAL @@ -217,7 +228,9 @@ array points outside the process's allocated address space. .Pp The .Fn pread -system call may also return the following errors: +and +.Fn preadv +system calls may also return the following errors: .Bl -tag -width Er .It Bq Er EINVAL The @@ -250,6 +263,10 @@ system calls are expected to conform to .St -xpg4.2 . .Sh HISTORY The +.Fn preadv +system call appeared in +.Fx 6.0 . +The .Fn pread function appeared in .At V.4 . diff --git a/lib/libc/sys/write.2 b/lib/libc/sys/write.2 index 7a7cd79..050e2a0 100644 --- a/lib/libc/sys/write.2 +++ b/lib/libc/sys/write.2 @@ -49,9 +49,11 @@ .Ft ssize_t .Fn write "int d" "const void *buf" "size_t nbytes" .Ft ssize_t +.Fn pwrite "int d" "const void *buf" "size_t nbytes" "off_t offset" +.Ft ssize_t .Fn writev "int d" "const struct iovec *iov" "int iovcnt" .Ft ssize_t -.Fn pwrite "int d" "const void *buf" "size_t nbytes" "off_t offset" +.Fn pwritev "int d" "const struct iovec *iov" "int iovcnt" "off_t offset" .Sh DESCRIPTION The .Fn write @@ -73,12 +75,16 @@ buffers specified by the members of the array: iov[0], iov[1], ..., iov[iovcnt\|-\|1]. The .Fn pwrite -system call -performs the same function, but writes to the specified position in +and +.Fn pwritev +system calls +perform the same functions, but write to the specified position in the file without modifying the file pointer. .Pp For -.Fn writev , +.Fn writev +and +.Fn pwritev, the .Fa iovec structure is defined as: @@ -143,8 +149,9 @@ is set to indicate the error. The .Fn write , .Fn writev , -and .Fn pwrite +and +.Fn pwritev system calls will fail and the file pointer will remain unchanged if: .Bl -tag -width Er @@ -201,6 +208,8 @@ is greater than .Pp In addition, .Fn writev +and +.Fn pwritev may return one of the following errors: .Bl -tag -width Er .It Bq Er EDESTADDRREQ @@ -233,7 +242,9 @@ The mbuf pool has been completely exhausted when writing to a socket. .Pp The .Fn pwrite -system call may also return the following errors: +and +.Fn pwritev +system calls may also return the following errors: .Bl -tag -width Er .It Bq Er EINVAL The @@ -261,6 +272,10 @@ system calls are expected to conform to .St -xpg4.2 . .Sh HISTORY The +.Fn pwritev +system call appeared in +.Fx 6.0 . +The .Fn pwrite function appeared in .At V.4 . diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index d21ced6..de4881e 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -764,6 +764,34 @@ freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) } int +freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) +{ + struct uio *auio; + int error; + + error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_preadv(td, uap->fd, auio, uap->offset); + free(auio, M_IOV); + return (error); +} + +int +freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) +{ + struct uio *auio; + int error; + + error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_pwritev(td, uap->fd, auio, uap->offset); + free(auio, M_IOV); + return (error); +} + +int freebsd32_settimeofday(struct thread *td, struct freebsd32_settimeofday_args *uap) { diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index c7fa7af..d861445 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -482,8 +482,15 @@ 286 AUE_NULL UNIMPL nosys 287 AUE_NULL UNIMPL nosys 288 AUE_NULL UNIMPL nosys -289 AUE_NULL UNIMPL nosys -290 AUE_NULL UNIMPL nosys +; 289 and 290 from NetBSD (OpenBSD: 267 and 268) +289 AUE_NULL MSTD { ssize_t freebsd32_preadv(int fd, \ + struct iovec32 *iovp, \ + u_int iovcnt, off_t offset); } +; XXX note - bigendian is different +290 AUE_NULL MSTD { ssize_t freebsd32_pwritev(int fd, \ + struct iovec32 *iovp, \ + u_int iovcnt, off_t offset); } +; XXX note - bigendian is different 291 AUE_NULL UNIMPL nosys 292 AUE_NULL UNIMPL nosys 293 AUE_NULL UNIMPL nosys diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index a3ae444..3c7199a 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -77,10 +77,10 @@ MALLOC_DEFINE(M_IOV, "iov", "large iov's"); static int pollscan(struct thread *, struct pollfd *, u_int); static int selscan(struct thread *, fd_mask **, fd_mask **, int); -static int dofileread(struct thread *, struct file *, int, void *, - size_t, off_t, int); -static int dofilewrite(struct thread *, struct file *, int, - const void *, size_t, off_t, int); +static int dofileread(struct thread *, int, struct file *, struct uio *, + off_t, int); +static int dofilewrite(struct thread *, int, struct file *, struct uio *, + off_t, int); static void doselwakeup(struct selinfo *, int); /* @@ -101,19 +101,24 @@ read(td, uap) struct thread *td; struct read_args *uap; { - struct file *fp; + struct uio auio; + struct iovec aiov; int error; - if ((error = fget_read(td, uap->fd, &fp)) == 0) { - error = dofileread(td, fp, uap->fd, uap->buf, - uap->nbyte, (off_t)-1, 0); - fdrop(fp, td); - } + if (uap->nbyte > INT_MAX) + return (EINVAL); + aiov.iov_base = uap->buf; + aiov.iov_len = uap->nbyte; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_resid = uap->nbyte; + auio.uio_segflg = UIO_USERSPACE; + error = kern_readv(td, uap->fd, &auio); return(error); } /* - * Pread system call + * Positioned read system call */ #ifndef _SYS_SYSPROTO_H_ struct pread_args { @@ -132,79 +137,20 @@ pread(td, uap) struct thread *td; struct pread_args *uap; { - struct file *fp; - int error; - - if ((error = fget_read(td, uap->fd, &fp)) != 0) - return (error); - if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) - error = ESPIPE; - else if (uap->offset < 0 && fp->f_vnode->v_type != VCHR) - error = EINVAL; - else { - error = dofileread(td, fp, uap->fd, uap->buf, uap->nbyte, - uap->offset, FOF_OFFSET); - } - fdrop(fp, td); - return(error); -} - -/* - * Code common for read and pread - */ -static int -dofileread(td, fp, fd, buf, nbyte, offset, flags) - struct thread *td; - struct file *fp; - int fd, flags; - void *buf; - size_t nbyte; - off_t offset; -{ struct uio auio; struct iovec aiov; - ssize_t cnt; - long error = 0; -#ifdef KTRACE - struct uio *ktruio = NULL; -#endif + int error; - /* Finish zero length reads right here */ - if (nbyte == 0) { - td->td_retval[0] = 0; - return(0); - } - aiov.iov_base = buf; - aiov.iov_len = nbyte; + if (uap->nbyte > INT_MAX) + return (EINVAL); + aiov.iov_base = uap->buf; + aiov.iov_len = uap->nbyte; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; - auio.uio_offset = offset; - if (nbyte > INT_MAX) - return (EINVAL); - auio.uio_resid = nbyte; - auio.uio_rw = UIO_READ; + auio.uio_resid = uap->nbyte; auio.uio_segflg = UIO_USERSPACE; - auio.uio_td = td; -#ifdef KTRACE - if (KTRPOINT(td, KTR_GENIO)) - ktruio = cloneuio(&auio); -#endif - cnt = nbyte; - - if ((error = fo_read(fp, &auio, td->td_ucred, flags, td))) { - if (auio.uio_resid != cnt && (error == ERESTART || - error == EINTR || error == EWOULDBLOCK)) - error = 0; - } - cnt -= auio.uio_resid; -#ifdef KTRACE - if (ktruio != NULL) { - ktruio->uio_resid = cnt; - ktrgenio(fd, UIO_READ, ktruio, error); - } -#endif - td->td_retval[0] = cnt; - return (error); + error = kern_preadv(td, uap->fd, &auio, uap->offset); + return(error); } /* @@ -238,29 +184,100 @@ int kern_readv(struct thread *td, int fd, struct uio *auio) { struct file *fp; - long cnt; int error; -#ifdef KTRACE - struct uio *ktruio = NULL; + + error = fget_read(td, fd, &fp); + if (error) + return (error); + error = dofileread(td, fd, fp, auio, (off_t)-1, 0); + fdrop(fp, td); + return (error); +} + +/* + * Scatter positioned read system call. + */ +#ifndef _SYS_SYSPROTO_H_ +struct preadv_args { + int fd; + struct iovec *iovp; + u_int iovcnt; + off_t offset; +}; #endif +/* + * MPSAFE + */ +int +preadv(struct thread *td, struct preadv_args *uap) +{ + struct uio *auio; + int error; + + error = copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_preadv(td, uap->fd, auio, uap->offset); + free(auio, M_IOV); + return (error); +} + +int +kern_preadv(td, fd, auio, offset) + struct thread *td; + int fd; + struct uio *auio; + off_t offset; +{ + struct file *fp; + int error; error = fget_read(td, fd, &fp); if (error) return (error); + if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) + error = ESPIPE; + else if (offset < 0 && fp->f_vnode->v_type != VCHR) + error = EINVAL; + else + error = dofileread(td, fd, fp, auio, offset, FOF_OFFSET); + fdrop(fp, td); + return (error); +} + +/* + * Common code for readv and preadv that reads data in + * from a file using the passed in uio, offset, and flags. + */ +static int +dofileread(td, fd, fp, auio, offset, flags) + struct thread *td; + int fd; + struct file *fp; + struct uio *auio; + off_t offset; + int flags; +{ + ssize_t cnt; + int error; +#ifdef KTRACE + struct uio *ktruio = NULL; +#endif + /* Finish zero length reads right here */ if (auio->uio_resid == 0) { td->td_retval[0] = 0; - fdrop(fp, td); return(0); } auio->uio_rw = UIO_READ; + auio->uio_offset = offset; auio->uio_td = td; #ifdef KTRACE if (KTRPOINT(td, KTR_GENIO)) ktruio = cloneuio(auio); #endif cnt = auio->uio_resid; - if ((error = fo_read(fp, auio, td->td_ucred, 0, td))) { + if ((error = fo_read(fp, auio, td->td_ucred, flags, td))) { if (auio->uio_resid != cnt && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -273,7 +290,6 @@ kern_readv(struct thread *td, int fd, struct uio *auio) } #endif td->td_retval[0] = cnt; - fdrop(fp, td); return (error); } @@ -295,21 +311,24 @@ write(td, uap) struct thread *td; struct write_args *uap; { - struct file *fp; + struct uio auio; + struct iovec aiov; int error; - if ((error = fget_write(td, uap->fd, &fp)) == 0) { - error = dofilewrite(td, fp, uap->fd, uap->buf, uap->nbyte, - (off_t)-1, 0); - fdrop(fp, td); - } else { - error = EBADF; /* XXX this can't be right */ - } + if (uap->nbyte > INT_MAX) + return (EINVAL); + aiov.iov_base = (void *)(uintptr_t)uap->buf; + aiov.iov_len = uap->nbyte; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_resid = uap->nbyte; + auio.uio_segflg = UIO_USERSPACE; + error = kern_writev(td, uap->fd, &auio); return(error); } /* - * Pwrite system call + * Positioned write system call */ #ifndef _SYS_SYSPROTO_H_ struct pwrite_args { @@ -328,80 +347,20 @@ pwrite(td, uap) struct thread *td; struct pwrite_args *uap; { - struct file *fp; - int error; - - if ((error = fget_write(td, uap->fd, &fp)) == 0) { - if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) - error = ESPIPE; - else if (uap->offset < 0 && fp->f_vnode->v_type != VCHR) - error = EINVAL; - else { - error = dofilewrite(td, fp, uap->fd, uap->buf, - uap->nbyte, uap->offset, FOF_OFFSET); - } - fdrop(fp, td); - } else { - error = EBADF; /* this can't be right */ - } - return(error); -} - -static int -dofilewrite(td, fp, fd, buf, nbyte, offset, flags) - struct thread *td; - struct file *fp; - int fd, flags; - const void *buf; - size_t nbyte; - off_t offset; -{ struct uio auio; struct iovec aiov; - ssize_t cnt; - long error = 0; -#ifdef KTRACE - struct uio *ktruio = NULL; -#endif + int error; - aiov.iov_base = (void *)(uintptr_t)buf; - aiov.iov_len = nbyte; + if (uap->nbyte > INT_MAX) + return (EINVAL); + aiov.iov_base = (void *)(uintptr_t)uap->buf; + aiov.iov_len = uap->nbyte; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; - auio.uio_offset = offset; - if (nbyte > INT_MAX) - return (EINVAL); - auio.uio_resid = nbyte; - auio.uio_rw = UIO_WRITE; + auio.uio_resid = uap->nbyte; auio.uio_segflg = UIO_USERSPACE; - auio.uio_td = td; -#ifdef KTRACE - if (KTRPOINT(td, KTR_GENIO)) - ktruio = cloneuio(&auio); -#endif - cnt = nbyte; - if (fp->f_type == DTYPE_VNODE) - bwillwrite(); - if ((error = fo_write(fp, &auio, td->td_ucred, flags, td))) { - if (auio.uio_resid != cnt && (error == ERESTART || - error == EINTR || error == EWOULDBLOCK)) - error = 0; - /* Socket layer is responsible for issuing SIGPIPE. */ - if (error == EPIPE && fp->f_type != DTYPE_SOCKET) { - PROC_LOCK(td->td_proc); - psignal(td->td_proc, SIGPIPE); - PROC_UNLOCK(td->td_proc); - } - } - cnt -= auio.uio_resid; -#ifdef KTRACE - if (ktruio != NULL) { - ktruio->uio_resid = cnt; - ktrgenio(fd, UIO_WRITE, ktruio, error); - } -#endif - td->td_retval[0] = cnt; - return (error); + error = kern_pwritev(td, uap->fd, &auio, uap->offset); + return(error); } /* @@ -435,17 +394,89 @@ int kern_writev(struct thread *td, int fd, struct uio *auio) { struct file *fp; - long cnt; int error; -#ifdef KTRACE - struct uio *ktruio = NULL; + + error = fget_write(td, fd, &fp); + if (error) + return (EBADF); /* XXX this can't be right */ + error = dofilewrite(td, fd, fp, auio, (off_t)-1, 0); + fdrop(fp, td); + return (error); +} + +/* + * Gather positioned write system call + */ +#ifndef _SYS_SYSPROTO_H_ +struct pwritev_args { + int fd; + struct iovec *iovp; + u_int iovcnt; + off_t offset; +}; #endif +/* + * MPSAFE + */ +int +pwritev(struct thread *td, struct pwritev_args *uap) +{ + struct uio *auio; + int error; + + error = copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_pwritev(td, uap->fd, auio, uap->offset); + free(auio, M_IOV); + return (error); +} + +int +kern_pwritev(td, fd, auio, offset) + struct thread *td; + struct uio *auio; + int fd; + off_t offset; +{ + struct file *fp; + int error; error = fget_write(td, fd, &fp); if (error) - return (EBADF); + return (EBADF); /* XXX this can't be right */ + if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) + error = ESPIPE; + else if (offset < 0 && fp->f_vnode->v_type != VCHR) + error = EINVAL; + else + error = dofilewrite(td, fd, fp, auio, offset, FOF_OFFSET); + fdrop(fp, td); + return (error); +} + +/* + * Common code for writev and pwritev that writes data to + * a file using the passed in uio, offset, and flags. + */ +static int +dofilewrite(td, fd, fp, auio, offset, flags) + struct thread *td; + int fd; + struct file *fp; + struct uio *auio; + off_t offset; + int flags; +{ + ssize_t cnt; + int error; +#ifdef KTRACE + struct uio *ktruio = NULL; +#endif + auio->uio_rw = UIO_WRITE; auio->uio_td = td; + auio->uio_offset = offset; #ifdef KTRACE if (KTRPOINT(td, KTR_GENIO)) ktruio = cloneuio(auio); @@ -453,10 +484,11 @@ kern_writev(struct thread *td, int fd, struct uio *auio) cnt = auio->uio_resid; if (fp->f_type == DTYPE_VNODE) bwillwrite(); - if ((error = fo_write(fp, auio, td->td_ucred, 0, td))) { + if ((error = fo_write(fp, auio, td->td_ucred, flags, td))) { if (auio->uio_resid != cnt && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; + /* Socket layer is responsible for issuing SIGPIPE. */ if (error == EPIPE) { PROC_LOCK(td->td_proc); psignal(td->td_proc, SIGPIPE); @@ -471,7 +503,6 @@ kern_writev(struct thread *td, int fd, struct uio *auio) } #endif td->td_retval[0] = cnt; - fdrop(fp, td); return (error); } diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index e2b9957..b9f1fce 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -502,8 +502,11 @@ 286 AUE_NULL UNIMPL nosys 287 AUE_NULL UNIMPL nosys 288 AUE_NULL UNIMPL nosys -289 AUE_NULL UNIMPL nosys -290 AUE_NULL UNIMPL nosys +; 289 and 290 from NetBSD (OpenBSD: 267 and 268) +289 AUE_NULL MSTD { ssize_t preadv(int fd, struct iovec *iovp, \ + u_int iovcnt, off_t offset); } +290 AUE_NULL MSTD { ssize_t pwritev(int fd, struct iovec *iovp, \ + u_int iovcnt, off_t offset); } 291 AUE_NULL UNIMPL nosys 292 AUE_NULL UNIMPL nosys 293 AUE_NULL UNIMPL nosys diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index cb9f84a..75d21e0 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -98,8 +98,10 @@ int kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, int mode); int kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name); +int kern_preadv(struct thread *td, int fd, struct uio *auio, off_t offset); int kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data); +int kern_pwritev(struct thread *td, int fd, struct uio *auio, off_t offset); int kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, int count); int kern_readv(struct thread *td, int fd, struct uio *auio); diff --git a/sys/sys/uio.h b/sys/sys/uio.h index cb3d4ae..b5c0ece 100644 --- a/sys/sys/uio.h +++ b/sys/sys/uio.h @@ -42,6 +42,11 @@ typedef __ssize_t ssize_t; #define _SSIZE_T_DECLARED #endif +#ifndef _OFF_T_DECLARED +typedef __off_t off_t; +#define _OFF_T_DECLARED +#endif + #if __BSD_VISIBLE enum uio_rw { UIO_READ, UIO_WRITE }; @@ -101,6 +106,8 @@ int uiomoveco(void *cp, int n, struct uio *uio, int disposable); __BEGIN_DECLS ssize_t readv(int, const struct iovec *, int); ssize_t writev(int, const struct iovec *, int); +ssize_t preadv(int, const struct iovec *, int, off_t); +ssize_t pwritev(int, const struct iovec *, int, off_t); __END_DECLS #endif /* _KERNEL */ |