kern/80362: [PATCH] add preadv() and pwritev() system calls
Marc Olzheim
marcolz at stack.nl
Tue Apr 26 06:20:37 PDT 2005
>Number: 80362
>Category: kern
>Synopsis: [PATCH] add preadv() and pwritev() system calls
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Tue Apr 26 13:20:30 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Marc Olzheim
>Release: FreeBSD 5.4-STABLE amd64
>Organization:
ilse media
>Environment:
FreeBSD 5.4-STABLE and FreeBSD 6.0-CURRENT
>Description:
FreeBSD lacks preadv() and pwritev(). Since all underlying code
already supports the functionality it is very easy to add.
NetBSD and OpenBSD have had these calls, that are useful in
multi-threaded fileaccess, for years now and for orthogonality
it's nice to have them as well.
>How-To-Repeat:
>Fix:
Patches for 5.4-STABLE and 6-CURRENT to follow:
5.4-STABLE.patch:
--- /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 11:31:56 2005
@@ -102,6 +102,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 posiotioned 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);
}
6-CURRENT.patch:
--- /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 12:14:46 2005
@@ -101,6 +101,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 posiotioned 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);
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list