summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_generic.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>1999-03-27 21:16:58 +0000
committeralc <alc@FreeBSD.org>1999-03-27 21:16:58 +0000
commitc9eccc7347cc4051a3db16f68f3a854908494917 (patch)
tree5921615b06b186f28e5d3133d7bc1b1a43ab944d /sys/kern/sys_generic.c
parent807da996a2d52fdc0c28d408fabc635bb3c681d4 (diff)
downloadFreeBSD-src-c9eccc7347cc4051a3db16f68f3a854908494917.zip
FreeBSD-src-c9eccc7347cc4051a3db16f68f3a854908494917.tar.gz
Added pread and pwrite. These functions are defined by the X/Open
Threads Extension. (Note: We use the same syscall numbers as NetBSD.) Submitted by: John Plevyak <jplevyak@inktomi.com>
Diffstat (limited to 'sys/kern/sys_generic.c')
-rw-r--r--sys/kern/sys_generic.c133
1 files changed, 132 insertions, 1 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index b607f71..e19fed8 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
- * $Id: sys_generic.c,v 1.44 1999/01/27 21:49:57 dillon Exp $
+ * $Id: sys_generic.c,v 1.45 1999/01/29 08:10:35 bde Exp $
*/
#include "opt_ktrace.h"
@@ -132,6 +132,70 @@ read(p, uap)
}
/*
+ * pread system call.
+ */
+#ifndef _SYS_SYSPROTO_H_
+struct pread_args {
+ int fd;
+ void *buf;
+ size_t nbyte;
+ off_t offset;
+};
+#endif
+/* ARGSUSED */
+int
+pread(p, uap)
+ struct proc *p;
+ register struct pread_args *uap;
+{
+ 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 (((u_int)uap->fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[uap->fd]) == NULL ||
+ (fp->f_flag & FREAD) == 0)
+ return (EBADF);
+ if (fp->f_type != DTYPE_VNODE)
+ return (ESPIPE);
+ aiov.iov_base = (caddr_t)uap->buf;
+ aiov.iov_len = uap->nbyte;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = uap->offset;
+ if (uap->nbyte > INT_MAX)
+ return (EINVAL);
+ auio.uio_resid = uap->nbyte;
+ auio.uio_rw = UIO_READ;
+ 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 = uap->nbyte;
+ if ((error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)))
+ if (auio.uio_resid != cnt && (error == ERESTART ||
+ error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ cnt -= auio.uio_resid;
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_GENIO) && error == 0)
+ ktrgenio(p->p_tracep, uap->fd, UIO_READ, &ktriov, cnt, error);
+#endif
+ p->p_retval[0] = cnt;
+ return (error);
+}
+
+/*
* Scatter read system call.
*/
#ifndef _SYS_SYSPROTO_H_
@@ -285,6 +349,73 @@ write(p, uap)
}
/*
+ * pwrite system call
+ */
+#ifndef _SYS_SYSPROTO_H_
+struct pwrite_args {
+ int fd;
+ const void *buf;
+ size_t nbyte;
+ off_t offset;
+};
+#endif
+int
+pwrite(p, uap)
+ struct proc *p;
+ register struct pwrite_args *uap;
+{
+ 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 (((u_int)uap->fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[uap->fd]) == NULL ||
+ (fp->f_flag & FWRITE) == 0)
+ return (EBADF);
+ if (fp->f_type != DTYPE_VNODE)
+ return (ESPIPE);
+ aiov.iov_base = (caddr_t)uap->buf;
+ aiov.iov_len = uap->nbyte;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = uap->offset;
+ if (uap->nbyte > INT_MAX)
+ return (EINVAL);
+ auio.uio_resid = 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 = uap->nbyte;
+ if ((error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred))) {
+ 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, uap->fd, UIO_WRITE,
+ &ktriov, cnt, error);
+#endif
+ p->p_retval[0] = cnt;
+ return (error);
+}
+
+/*
* Gather write system call
*/
#ifndef _SYS_SYSPROTO_H_
OpenPOWER on IntegriCloud