summaryrefslogtreecommitdiff
path: root/sys/compat
diff options
context:
space:
mode:
authorkstailey <kstailey@cvs.openbsd.org>1999-09-17 13:41:30 +0000
committerkstailey <kstailey@cvs.openbsd.org>1999-09-17 13:41:30 +0000
commit94614cae4576243ee91363ef921a364dc5abdc20 (patch)
treec1ec8445579da3ffc4183fe63fa91d30bdd63159 /sys/compat
parentba903d4dd684a871a55c21d616e2dcfab110e3c9 (diff)
rest of pread() etc., fdatasync() hack
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/netbsd/netbsd_misc.c33
-rw-r--r--sys/compat/netbsd/netbsd_pos_io.c217
-rw-r--r--sys/compat/netbsd/syscalls.master5
3 files changed, 239 insertions, 16 deletions
diff --git a/sys/compat/netbsd/netbsd_misc.c b/sys/compat/netbsd/netbsd_misc.c
index 45559be3ed4..6eadffd8da7 100644
--- a/sys/compat/netbsd/netbsd_misc.c
+++ b/sys/compat/netbsd/netbsd_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netbsd_misc.c,v 1.3 1999/09/16 13:20:06 kstailey Exp $ */
+/* $OpenBSD: netbsd_misc.c,v 1.4 1999/09/17 13:41:29 kstailey Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@@ -38,10 +38,14 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
+ * @(#)vfs_syscalls.c 8.28 (Berkeley) 12/10/94
*/
#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/mount.h>
#include <sys/proc.h>
+#include <sys/vnode.h>
#include <compat/netbsd/netbsd_types.h>
#include <compat/netbsd/netbsd_signal.h>
@@ -57,3 +61,30 @@ netbsd_sys___vfork14(p, v, retval)
{
return (fork1(p, ISVFORK, 0, NULL, 0, retval));
}
+
+/* XXX syncs whole file */
+/*ARGSUSED*/
+int
+netbsd_sys_fdatasync(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_fdatasync_args /* {
+ syscallarg(int) fd;
+ } */ *uap = v;
+ register struct vnode *vp;
+ struct file *fp;
+ int error;
+
+ if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
+ return (error);
+ vp = (struct vnode *)fp->f_data;
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ if ((error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p)) == 0 &&
+ bioops.io_fsync != NULL)
+ error = (*bioops.io_fsync)(vp);
+
+ VOP_UNLOCK(vp, 0, p);
+ return (error);
+}
diff --git a/sys/compat/netbsd/netbsd_pos_io.c b/sys/compat/netbsd/netbsd_pos_io.c
index 7281901d72a..9cb98f9bff0 100644
--- a/sys/compat/netbsd/netbsd_pos_io.c
+++ b/sys/compat/netbsd/netbsd_pos_io.c
@@ -1,9 +1,10 @@
-/* $OpenBSD: netbsd_pos_io.c,v 1.2 1999/09/17 12:37:54 kstailey Exp $ */
+/* $OpenBSD: netbsd_pos_io.c,v 1.3 1999/09/17 13:41:29 kstailey Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
- * Copyright (c) 1989, 1993
+ * Copyright (c) 1996 Theo de Raadt
+ * Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
@@ -40,6 +41,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.28 (Berkeley) 12/10/94
+ * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
*/
#include <sys/param.h>
@@ -47,8 +49,9 @@
#include <sys/filedesc.h>
#include <sys/vnode.h>
#include <sys/proc.h>
+#include <sys/signalvar.h>
#include <sys/uio.h>
-/*#include <sys/malloc.h>*/
+#include <sys/malloc.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
@@ -162,16 +165,86 @@ netbsd_sys_preadv(p, v, retval)
void *v;
register_t *retval;
{
-#if 0
struct netbsd_sys_preadv_args /* {
syscallarg(int) fd;
syscallarg(const struct iovec *) iovp;
syscallarg(int) iovcnt;
syscallarg(off_t) offset;
} */ *uap = v;
-#else
- return (0);
+ register struct file *fp;
+ register struct filedesc *fdp = p->p_fd;
+ struct uio auio;
+ register struct iovec *iov;
+ struct iovec *needfree;
+ struct iovec aiov[UIO_SMALLIOV];
+ long i, cnt, error = 0;
+ u_int iovlen;
+#ifdef KTRACE
+ struct iovec *ktriov = NULL;
+#endif
+
+ if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset))))
+ return (error);
+ fp = fdp->fd_ofiles[SCARG(uap, fd)];
+ if (SCARG(uap, iovcnt) <= 0)
+ return (EINVAL);
+ /* note: can't use iovlen until iovcnt is validated */
+ iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
+ if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
+ if (SCARG(uap, iovcnt) > IOV_MAX)
+ return (EINVAL);
+ MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
+ needfree = iov;
+ } else {
+ iov = aiov;
+ needfree = NULL;
+ }
+ auio.uio_iov = iov;
+ auio.uio_iovcnt = SCARG(uap, iovcnt);
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_procp = p;
+ error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
+ if (error)
+ goto done;
+ auio.uio_resid = 0;
+ for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
+ /* Don't allow sum > SSIZE_MAX */
+ if (iov->iov_len > SSIZE_MAX ||
+ (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
+ error = EINVAL;
+ goto done;
+ }
+ }
+#ifdef KTRACE
+ /*
+ * if tracing, save a copy of iovec
+ */
+ if (KTRPOINT(p, KTR_GENIO)) {
+ MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
+ bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
+ }
+#endif
+ cnt = auio.uio_resid;
+ error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
+ if (error)
+ if (auio.uio_resid != cnt && (error == ERESTART ||
+ error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ cnt -= auio.uio_resid;
+#ifdef KTRACE
+ if (ktriov != NULL) {
+ if (error == 0)
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, ktriov,
+ cnt, error);
+ FREE(ktriov, M_TEMP);
+ }
#endif
+ *retval = cnt;
+done:
+ if (needfree)
+ FREE(needfree, M_IOV);
+ return (error);
}
/*
@@ -184,16 +257,61 @@ netbsd_sys_pwrite(p, v, retval)
void *v;
register_t *retval;
{
-#if 0
struct netbsd_sys_pwrite_args /* {
syscallarg(int) fd;
syscallarg(const void *) buf;
syscallarg(size_t) nbyte;
syscallarg(off_t) offset;
} */ *uap = v;
-#else
- return (0);
+ register struct file *fp;
+ register struct filedesc *fdp = p->p_fd;
+ struct uio auio;
+ struct iovec aiov;
+ long cnt, error = 0;
+#ifdef KTRACE
+ struct iovec ktriov;
+#endif
+
+ if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset))))
+ return (error);
+ fp = fdp->fd_ofiles[SCARG(uap, fd)];
+ if ((fp->f_flag & FWRITE) == 0)
+ return (EBADF);
+ /* Don't allow nbyte to be larger than max return val */
+ if (SCARG(uap, nbyte) > SSIZE_MAX)
+ return(EINVAL);
+ aiov.iov_base = (caddr_t)SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, nbyte);
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_resid = SCARG(uap, nbyte);
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_procp = p;
+#ifdef KTRACE
+ /*
+ * if tracing, save a copy of iovec
+ */
+ if (KTRPOINT(p, KTR_GENIO))
+ ktriov = aiov;
+#endif
+ cnt = SCARG(uap, nbyte);
+ error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
+ if (error) {
+ 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 (KTRPOINT(p, KTR_GENIO) && error == 0)
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
+ &ktriov, cnt, error);
#endif
+ *retval = cnt;
+ return (error);
}
/*
@@ -206,14 +324,89 @@ netbsd_sys_pwritev(p, v, retval)
void *v;
register_t *retval;
{
-#if 0
struct netbsd_sys_pwritev_args /* {
syscallarg(int) fd;
syscallarg(const struct iovec *) iovp;
syscallarg(int) iovcnt;
syscallarg(off_t) offset;
} */ *uap = v;
-#else
- return (0);
+ register struct file *fp;
+ register struct filedesc *fdp = p->p_fd;
+ struct uio auio;
+ register struct iovec *iov;
+ struct iovec *needfree;
+ struct iovec aiov[UIO_SMALLIOV];
+ long i, cnt, error = 0;
+ u_int iovlen;
+#ifdef KTRACE
+ struct iovec *ktriov = NULL;
+#endif
+
+ if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset))))
+ return (error);
+ fp = fdp->fd_ofiles[SCARG(uap, fd)];
+ if ((fp->f_flag & FWRITE) == 0)
+ return (EBADF);
+ if (SCARG(uap, iovcnt) <= 0)
+ return (EINVAL);
+ /* note: can't use iovlen until iovcnt is validated */
+ iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
+ if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
+ if (SCARG(uap, iovcnt) > IOV_MAX)
+ return (EINVAL);
+ MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
+ needfree = iov;
+ } else {
+ iov = aiov;
+ needfree = NULL;
+ }
+ auio.uio_iov = iov;
+ auio.uio_iovcnt = SCARG(uap, iovcnt);
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_procp = p;
+ error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
+ if (error)
+ goto done;
+ auio.uio_resid = 0;
+ for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
+ /* Don't allow sum > SSIZE_MAX */
+ if (iov->iov_len > SSIZE_MAX ||
+ (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
+ error = EINVAL;
+ goto done;
+ }
+ }
+#ifdef KTRACE
+ /*
+ * if tracing, save a copy of iovec
+ */
+ if (KTRPOINT(p, KTR_GENIO)) {
+ MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
+ bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
+ }
+#endif
+ cnt = auio.uio_resid;
+ error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
+ if (error) {
+ 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 (ktriov != NULL) {
+ if (error == 0)
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
+ ktriov, cnt, error);
+ FREE(ktriov, M_TEMP);
+ }
#endif
+ *retval = cnt;
+done:
+ if (needfree)
+ FREE(needfree, M_IOV);
+ return (error);
}
diff --git a/sys/compat/netbsd/syscalls.master b/sys/compat/netbsd/syscalls.master
index 5f96d87747a..c1b5a251691 100644
--- a/sys/compat/netbsd/syscalls.master
+++ b/sys/compat/netbsd/syscalls.master
@@ -1,4 +1,4 @@
-; $OpenBSD: syscalls.master,v 1.6 1999/09/17 12:13:47 kstailey Exp $
+; $OpenBSD: syscalls.master,v 1.7 1999/09/17 13:41:29 kstailey Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@@ -506,8 +506,7 @@
;
240 NOARGS { int sys_nanosleep(const struct timespec *rqtp, \
struct timespec *rmtp); }
-241 UNIMPL
-;241 STD { int sys_fdatasync(int fd); }
+241 STD { int netbsd_sys_fdatasync(int fd); }
242 UNIMPL
243 UNIMPL
244 UNIMPL