On Tue, Apr 26, 2005 at 03:31:15PM +0200, Marc Olzheim wrote:
> Ok, I cleaned up the patch, got the freebsd32-compat working and filed a
> PR: http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/80362

Thanks to some people commenting, I've fixed a typo and added the off_t
typedef in sys/uio.h, so that a buildworld now survives as well. :-)

The diffs between the current- and stable- patch are now purely line
number differences.

I've got it running on my company's servers and everything seems to work
ok. We don't use the freebsd32 compat part though, so I hope I've done
that ok.

Marc
--- /usr/src/lib/libc/sys/read.2        Sat Nov 13 12:55:41 2004
+++ /usr/src/lib/libc/sys/read.2        Tue Apr 26 14:01:23 2005
@@ -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 @@
 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 @@
 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 @@
 The
 .Fn read ,
 .Fn readv ,
-and
 .Fn pread
+and
+.Fn preadv
 system calls
 will succeed unless:
 .Bl -tag -width Er
@@ -184,6 +193,8 @@
 .Pp
 In addition,
 .Fn readv
+and
+.Fn preadv
 may return one of the following errors:
 .Bl -tag -width Er
 .It Bq Er EINVAL
@@ -212,7 +223,9 @@
 .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
@@ -244,6 +257,10 @@
 system calls are expected to conform to
 .St -xpg4.2 .
 .Sh HISTORY
+The
+.Fn preadv
+system call appeared in
+.Fx 5.4 .
 The
 .Fn pread
 function appeared in
--- /usr/src/lib/libc/sys/write.2       Sat Nov 13 12:55:41 2004
+++ /usr/src/lib/libc/sys/write.2       Tue Apr 26 13:59:59 2005
@@ -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 @@
 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 @@
 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
@@ -196,6 +203,8 @@
 .Pp
 In addition,
 .Fn writev
+and
+.Fn pwritev
 may return one of the following errors:
 .Bl -tag -width Er
 .It Bq Er EDESTADDRREQ
@@ -228,7 +237,9 @@
 .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
@@ -255,6 +266,10 @@
 system calls are expected to conform to
 .St -xpg4.2 .
 .Sh HISTORY
+The
+.Fn pwritev
+system call appeared in
+.Fx 5.4 .
 The
 .Fn pwrite
 function appeared in
--- /usr/src/sys/sys/syscallsubr.h      Tue Apr 26 13:35:50 2005
+++ /usr/src/sys/sys/syscallsubr.h      Tue Apr 26 13:36:56 2005
@@ -91,8 +91,12 @@
            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 flags);
 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 flags);
 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);
--- /usr/src/sys/sys/uio.h      Tue Feb  1 00:26:57 2005
+++ /usr/src/sys/sys/uio.h      Tue Apr 26 21:16:37 2005
@@ -42,6 +42,11 @@
 #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 };
 
@@ -102,6 +107,8 @@
 __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 */
--- /usr/src/sys/kern/syscalls.master   Tue Apr 26 11:28:55 2005
+++ /usr/src/sys/kern/syscalls.master   Tue Apr 26 11:31:56 2005
@@ -411,8 +411,11 @@
 286    UNIMPL  nosys
 287    UNIMPL  nosys
 288    UNIMPL  nosys
-289    UNIMPL  nosys
-290    UNIMPL  nosys
+; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
+289    MSTD    { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt,\
+                   off_t offset); }
+290    MSTD    { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt,\
+                   off_t offset); }
 291    UNIMPL  nosys
 292    UNIMPL  nosys
 293    UNIMPL  nosys
--- /usr/src/sys/kern/sys_generic.c     Tue Apr 26 11:28:55 2005
+++ /usr/src/sys/kern/sys_generic.c     Tue Apr 26 13:37:57 2005
@@ -232,9 +232,47 @@
        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, FOF_OFFSET);
+       free(auio, M_IOV);
+       return (error);
+}
+
 int
 kern_readv(struct thread *td, int fd, struct uio *auio)
 {
+       return (kern_preadv(td, fd, auio, (off_t)-1, 0));
+}
+
+int
+kern_preadv(td, fd, auio, offset, flags)
+       struct thread *td;
+       struct uio *auio;
+       int fd, flags;
+       off_t offset;
+{
        struct file *fp;
        long cnt;
        int error;
@@ -252,13 +290,14 @@
                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;
@@ -428,9 +467,47 @@
        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, FOF_OFFSET);
+       free(auio, M_IOV);
+       return (error);
+}
+
 int
 kern_writev(struct thread *td, int fd, struct uio *auio)
 {
+       return (kern_pwritev(td, fd, auio, (off_t)-1, 0));
+}
+
+int
+kern_pwritev(td, fd, auio, offset, flags)
+       struct thread *td;
+       struct uio *auio;
+       int fd, flags;
+       off_t offset;
+{
        struct file *fp;
        long cnt;
        int error;
@@ -443,6 +520,7 @@
                return (EBADF);
        auio->uio_rw = UIO_WRITE;
        auio->uio_td = td;
+       auio->uio_offset = offset;
 #ifdef KTRACE
        if (KTRPOINT(td, KTR_GENIO))
                ktruio = cloneuio(auio);
@@ -450,7 +528,7 @@
        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;
--- /usr/src/sys/compat/freebsd32/syscalls.master       Tue Apr 26 11:28:51 2005
+++ /usr/src/sys/compat/freebsd32/syscalls.master       Tue Apr 26 13:52:46 2005
@@ -406,8 +406,13 @@
 286    UNIMPL  nosys
 287    UNIMPL  nosys
 288    UNIMPL  nosys
-289    UNIMPL  nosys
-290    UNIMPL  nosys
+; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
+289    STD { ssize_t freebsd32_preadv(int fd, struct iovec32 *iovp,\
+                   u_int iovcnt, off_t offset); }
+; XXX note - bigendian is different
+290    STD { ssize_t freebsd32_pwritev(int fd, struct iovec32 *iovp,\
+                   u_int iovcnt, off_t offset); }
+; XXX note - bigendian is different
 291    UNIMPL  nosys
 292    UNIMPL  nosys
 293    UNIMPL  nosys
--- /usr/src/sys/compat/freebsd32/freebsd32_misc.c      Tue Apr 26 13:38:38 2005
+++ /usr/src/sys/compat/freebsd32/freebsd32_misc.c      Tue Apr 26 13:45:17 2005
@@ -694,7 +694,7 @@
        error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
        if (error)
                return (error);
-       error = kern_readv(td, uap->fd, auio);
+       error = kern_preadv(td, uap->fd, auio, (off_t)-1, 0);
        free(auio, M_IOV);
        return (error);
 }
@@ -708,7 +708,35 @@
        error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
        if (error)
                return (error);
-       error = kern_writev(td, uap->fd, auio);
+       error = kern_pwritev(td, uap->fd, auio, (off_t)-1, 0);
+       free(auio, M_IOV);
+       return (error);
+}
+
+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, FOF_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, FOF_OFFSET);
        free(auio, M_IOV);
        return (error);
 }
--- /usr/src/lib/libc/sys/read.2        Tue Apr 26 12:15:30 2005
+++ /usr/src/lib/libc/sys/read.2        Tue Apr 26 14:03:07 2005
@@ -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 @@
 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 @@
 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 @@
 The
 .Fn read ,
 .Fn readv ,
-and
 .Fn pread
+and
+.Fn preadv
 system calls
 will succeed unless:
 .Bl -tag -width Er
@@ -189,6 +198,8 @@
 .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 @@
 .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
@@ -249,6 +262,10 @@
 system calls are expected to conform to
 .St -xpg4.2 .
 .Sh HISTORY
+The
+.Fn preadv
+system call appeared in
+.Fx 5.4 .
 The
 .Fn pread
 function appeared in
--- /usr/src/lib/libc/sys/write.2       Tue Apr 26 12:15:43 2005
+++ /usr/src/lib/libc/sys/write.2       Tue Apr 26 12:30:34 2005
@@ -50,9 +50,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
@@ -74,12 +76,16 @@
 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:
@@ -144,8 +150,9 @@
 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
@@ -202,6 +209,8 @@
 .Pp
 In addition,
 .Fn writev
+and
+.Fn pwritev
 may return one of the following errors:
 .Bl -tag -width Er
 .It Bq Er EDESTADDRREQ
@@ -234,7 +243,9 @@
 .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 5.4 .
 The
 .Fn pwrite
 function appeared in
--- /usr/src/sys/sys/syscallsubr.h      Tue Apr 26 13:22:49 2005
+++ /usr/src/sys/sys/syscallsubr.h      Tue Apr 26 13:22:27 2005
@@ -96,8 +96,12 @@
            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 flags);
 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 flags);
 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);
--- /usr/src/sys/sys/uio.h      Fri Jan  7 03:29:24 2005
+++ /usr/src/sys/sys/uio.h      Tue Apr 26 21:19:52 2005
@@ -42,6 +42,11 @@
 #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 @@
 __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 */
--- /usr/src/sys/kern/syscalls.master   Sat Apr 23 04:36:07 2005
+++ /usr/src/sys/kern/syscalls.master   Tue Apr 26 12:14:46 2005
@@ -411,8 +411,11 @@
 286    UNIMPL  nosys
 287    UNIMPL  nosys
 288    UNIMPL  nosys
-289    UNIMPL  nosys
-290    UNIMPL  nosys
+; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
+289    MSTD    { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt,\
+                   off_t offset); }
+290    MSTD    { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt,\
+                   off_t offset); }
 291    UNIMPL  nosys
 292    UNIMPL  nosys
 293    UNIMPL  nosys
--- /usr/src/sys/kern/sys_generic.c     Fri Apr  1 00:51:18 2005
+++ /usr/src/sys/kern/sys_generic.c     Tue Apr 26 13:21:15 2005
@@ -233,9 +233,47 @@
        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, FOF_OFFSET);
+       free(auio, M_IOV);
+       return (error);
+}
+
 int
 kern_readv(struct thread *td, int fd, struct uio *auio)
 {
+       return (kern_preadv(td, fd, auio, (off_t)-1, 0));
+}
+
+int
+kern_preadv(td, fd, auio, offset, flags)
+       struct thread *td;
+       struct uio *auio;
+       int fd, flags;
+       off_t offset;
+{
        struct file *fp;
        long cnt;
        int error;
@@ -253,13 +291,14 @@
                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;
@@ -430,9 +469,47 @@
        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, FOF_OFFSET);
+       free(auio, M_IOV);
+       return (error);
+}
+
 int
 kern_writev(struct thread *td, int fd, struct uio *auio)
 {
+       return (kern_pwritev(td, fd, auio, (off_t)-1, 0));
+}
+
+int
+kern_pwritev(td, fd, auio, offset, flags)
+       struct thread *td;
+       struct uio *auio;
+       int fd, flags;
+       off_t offset;
+{
        struct file *fp;
        long cnt;
        int error;
@@ -445,6 +522,7 @@
                return (EBADF);
        auio->uio_rw = UIO_WRITE;
        auio->uio_td = td;
+       auio->uio_offset = offset;
 #ifdef KTRACE
        if (KTRPOINT(td, KTR_GENIO))
                ktruio = cloneuio(auio);
@@ -452,7 +530,7 @@
        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;
--- /usr/src/sys/compat/freebsd32/syscalls.master       Tue Mar  1 07:32:53 2005
+++ /usr/src/sys/compat/freebsd32/syscalls.master       Tue Apr 26 13:52:24 2005
@@ -406,8 +406,13 @@
 286    UNIMPL  nosys
 287    UNIMPL  nosys
 288    UNIMPL  nosys
-289    UNIMPL  nosys
-290    UNIMPL  nosys
+; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
+289    STD { ssize_t freebsd32_preadv(int fd, struct iovec32 *iovp,\
+                   u_int iovcnt, off_t offset); }
+; XXX note - bigendian is different
+290    STD { ssize_t freebsd32_pwritev(int fd, struct iovec32 *iovp,\
+                   u_int iovcnt, off_t offset); }
+; XXX note - bigendian is different
 291    UNIMPL  nosys
 292    UNIMPL  nosys
 293    UNIMPL  nosys
--- /usr/src/sys/compat/freebsd32/freebsd32_misc.c      Tue Apr 26 13:14:09 2005
+++ /usr/src/sys/compat/freebsd32/freebsd32_misc.c      Tue Apr 26 13:32:54 2005
@@ -733,7 +733,7 @@
        error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
        if (error)
                return (error);
-       error = kern_readv(td, uap->fd, auio);
+       error = kern_preadv(td, uap->fd, auio, (off_t)-1, 0);
        free(auio, M_IOV);
        return (error);
 }
@@ -747,7 +747,35 @@
        error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
        if (error)
                return (error);
-       error = kern_writev(td, uap->fd, auio);
+       error = kern_pwritev(td, uap->fd, auio, (off_t)-1, 0);
+       free(auio, M_IOV);
+       return (error);
+}
+
+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, FOF_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, FOF_OFFSET);
        free(auio, M_IOV);
        return (error);
 }

Attachment: pgpUwN9c4yKlk.pgp
Description: PGP signature

Reply via email to