Add standard padding argument to pread and pwrite syscall. That should make them

NetBSD compatible.

Add parameter to fo_read and fo_write. (The only flag FOF_OFFSET mean that
the offset is set in the struct uio).

Factor out some common code from read/pread/write/pwrite syscalls.
This commit is contained in:
dt 1999-04-04 21:41:28 +00:00
parent bd8e7f40fb
commit f13dd5fa6d
8 changed files with 129 additions and 158 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
* $Id: sys_generic.c,v 1.45 1999/01/29 08:10:35 bde Exp $
* $Id: sys_generic.c,v 1.46 1999/03/27 21:16:33 alc Exp $
*/
#include "opt_ktrace.h"
@ -69,6 +69,25 @@ MALLOC_DEFINE(M_IOV, "iov", "large iov's");
static int pollscan __P((struct proc *, struct pollfd *, int));
static int selscan __P((struct proc *, fd_mask **, fd_mask **, int));
static struct file* getfp __P((struct filedesc *, int, int));
static int dofileread __P((struct proc *, struct file *, int, void *,
size_t, off_t, int));
static int dofilewrite __P((struct proc *, struct file *, int,
const void *, size_t, off_t, int));
static struct file*
getfp(fdp, fd, flag)
struct filedesc* fdp;
int fd, flag;
{
struct file* fp;
if (((u_int)fd) >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[fd]) == NULL ||
(fp->f_flag & flag) == 0)
return (NULL);
return (fp);
}
/*
* Read system call.
@ -80,76 +99,57 @@ struct read_args {
size_t nbyte;
};
#endif
/* ARGSUSED */
int
read(p, uap)
struct proc *p;
register struct read_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)
if ((fp = getfp(p->p_fd, uap->fd, FREAD)) == NULL)
return (EBADF);
aiov.iov_base = (caddr_t)uap->buf;
aiov.iov_len = uap->nbyte;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = -1;
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);
return (dofileread(p, fp, uap->fd, uap->buf, uap->nbyte, (off_t)-1, 0));
}
/*
* pread system call.
* Pread system call
*/
#ifndef _SYS_SYSPROTO_H_
struct pread_args {
int fd;
void *buf;
size_t nbyte;
off_t offset;
int pad;
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;
if ((fp = getfp(p->p_fd, uap->fd, FREAD)) == NULL)
return (EBADF);
if (fp->f_type != DTYPE_VNODE)
return (ESPIPE);
return (dofileread(p, fp, uap->fd, uap->buf, uap->nbyte, uap->offset,
FOF_OFFSET));
}
/*
* Code common for read and pread
*/
int
dofileread(p, fp, fd, buf, nbyte, offset, flags)
struct proc *p;
struct file *fp;
int fd, flags;
void *buf;
size_t nbyte;
off_t offset;
{
struct uio auio;
struct iovec aiov;
long cnt, error = 0;
@ -157,20 +157,14 @@ pread(p, uap)
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;
aiov.iov_base = (caddr_t)buf;
aiov.iov_len = nbyte;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = uap->offset;
if (uap->nbyte > INT_MAX)
auio.uio_offset = offset;
if (nbyte > INT_MAX)
return (EINVAL);
auio.uio_resid = uap->nbyte;
auio.uio_resid = nbyte;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
@ -181,15 +175,15 @@ pread(p, uap)
if (KTRPOINT(p, KTR_GENIO))
ktriov = aiov;
#endif
cnt = uap->nbyte;
if ((error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)))
cnt = nbyte;
if ((error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred, flags)))
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);
ktrgenio(p->p_tracep, fd, UIO_READ, &ktriov, cnt, error);
#endif
p->p_retval[0] = cnt;
return (error);
@ -222,9 +216,7 @@ readv(p, uap)
struct iovec *ktriov = NULL;
#endif
if (((u_int)uap->fd) >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[uap->fd]) == NULL ||
(fp->f_flag & FREAD) == 0)
if ((fp = getfp(fdp, uap->fd, FREAD)) == NULL)
return (EBADF);
/* note: can't use iovlen until iovcnt is validated */
iovlen = uap->iovcnt * sizeof (struct iovec);
@ -264,7 +256,7 @@ readv(p, uap)
}
#endif
cnt = auio.uio_resid;
if ((error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)))
if ((error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred, 0)))
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
@ -300,63 +292,22 @@ write(p, uap)
register struct write_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)
if ((fp = getfp(p->p_fd, uap->fd, FWRITE)) == NULL)
return (EBADF);
aiov.iov_base = uap->buf;
aiov.iov_len = uap->nbyte;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = -1;
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);
return (dofilewrite(p, fp, uap->fd, uap->buf, uap->nbyte, (off_t)-1, 0));
}
/*
* pwrite system call
* Pwrite system call
*/
#ifndef _SYS_SYSPROTO_H_
struct pwrite_args {
int fd;
const void *buf;
size_t nbyte;
off_t offset;
int pad;
off_t offset;
};
#endif
int
@ -365,7 +316,24 @@ pwrite(p, uap)
register struct pwrite_args *uap;
{
register struct file *fp;
register struct filedesc *fdp = p->p_fd;
if ((fp = getfp(p->p_fd, uap->fd, FWRITE)) == NULL)
return (EBADF);
if (fp->f_type != DTYPE_VNODE)
return (ESPIPE);
return (dofilewrite(p, fp, uap->fd, uap->buf, uap->nbyte, uap->offset,
FOF_OFFSET));
}
static int
dofilewrite(p, fp, fd, buf, nbyte, offset, flags)
struct proc *p;
struct file *fp;
int fd, flags;
const void *buf;
size_t nbyte;
off_t offset;
{
struct uio auio;
struct iovec aiov;
long cnt, error = 0;
@ -373,20 +341,14 @@ pwrite(p, uap)
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;
aiov.iov_base = (void *)buf;
aiov.iov_len = nbyte;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = uap->offset;
if (uap->nbyte > INT_MAX)
auio.uio_offset = offset;
if (nbyte > INT_MAX)
return (EINVAL);
auio.uio_resid = uap->nbyte;
auio.uio_resid = nbyte;
auio.uio_rw = UIO_WRITE;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
@ -397,8 +359,8 @@ pwrite(p, uap)
if (KTRPOINT(p, KTR_GENIO))
ktriov = aiov;
#endif
cnt = uap->nbyte;
if ((error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred))) {
cnt = nbyte;
if ((error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred, flags))) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
@ -408,7 +370,7 @@ pwrite(p, uap)
cnt -= auio.uio_resid;
#ifdef KTRACE
if (KTRPOINT(p, KTR_GENIO) && error == 0)
ktrgenio(p->p_tracep, uap->fd, UIO_WRITE,
ktrgenio(p->p_tracep, fd, UIO_WRITE,
&ktriov, cnt, error);
#endif
p->p_retval[0] = cnt;
@ -442,9 +404,7 @@ writev(p, uap)
struct iovec *ktriov = NULL;
#endif
if (((u_int)uap->fd) >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[uap->fd]) == NULL ||
(fp->f_flag & FWRITE) == 0)
if ((fp = getfp(fdp, uap->fd, FWRITE)) == NULL)
return (EBADF);
/* note: can't use iovlen until iovcnt is validated */
iovlen = uap->iovcnt * sizeof (struct iovec);
@ -484,7 +444,7 @@ writev(p, uap)
}
#endif
cnt = auio.uio_resid;
if ((error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred))) {
if ((error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred, 0))) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;

View File

@ -16,7 +16,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
* $Id: sys_pipe.c,v 1.49 1999/01/28 00:57:47 dillon Exp $
* $Id: sys_pipe.c,v 1.50 1999/02/04 23:50:49 dillon Exp $
*/
/*
@ -88,9 +88,9 @@
* interfaces to the outside world
*/
static int pipe_read __P((struct file *fp, struct uio *uio,
struct ucred *cred));
struct ucred *cred, int flags));
static int pipe_write __P((struct file *fp, struct uio *uio,
struct ucred *cred));
struct ucred *cred, int flags));
static int pipe_close __P((struct file *fp, struct proc *p));
static int pipe_poll __P((struct file *fp, int events, struct ucred *cred,
struct proc *p));
@ -319,10 +319,11 @@ pipeselwakeup(cpipe)
/* ARGSUSED */
static int
pipe_read(fp, uio, cred)
pipe_read(fp, uio, cred, flags)
struct file *fp;
struct uio *uio;
struct ucred *cred;
int flags;
{
struct pipe *rpipe = (struct pipe *) fp->f_data;
@ -702,10 +703,11 @@ pipe_direct_write(wpipe, uio)
#endif
static int
pipe_write(fp, uio, cred)
pipe_write(fp, uio, cred, flags)
struct file *fp;
struct uio *uio;
struct ucred *cred;
int flags;
{
int error = 0;
int orig_resid;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)sys_socket.c 8.1 (Berkeley) 6/10/93
* $Id: sys_socket.c,v 1.22 1999/02/01 13:24:39 newton Exp $
* $Id: sys_socket.c,v 1.23 1999/02/01 21:16:29 newton Exp $
*/
#include <sys/param.h>
@ -54,10 +54,11 @@ struct fileops socketops =
/* ARGSUSED */
int
soo_read(fp, uio, cred)
soo_read(fp, uio, cred, flags)
struct file *fp;
struct uio *uio;
struct ucred *cred;
int flags;
{
struct socket *so = (struct socket *)fp->f_data;
return so->so_proto->pr_usrreqs->pru_soreceive(so, 0, uio, 0, 0, 0);
@ -65,10 +66,11 @@ soo_read(fp, uio, cred)
/* ARGSUSED */
int
soo_write(fp, uio, cred)
soo_write(fp, uio, cred, flags)
struct file *fp;
struct uio *uio;
struct ucred *cred;
int flags;
{
struct socket *so = (struct socket *)fp->f_data;
return so->so_proto->pr_usrreqs->pru_sosend(so, 0, uio, 0, 0, 0,

View File

@ -1,4 +1,4 @@
$Id: syscalls.master,v 1.55 1998/11/11 12:45:14 peter Exp $
$Id: syscalls.master,v 1.56 1999/03/27 21:16:33 alc Exp $
; from: @(#)syscalls.master 8.2 (Berkeley) 1/13/94
;
; System call name/number master file.
@ -266,8 +266,10 @@
171 STD BSD { int shmsys(int which, int a2, int a3, int a4); }
; XXX should be { int shmsys(int which, ...); }
172 UNIMPL NOHIDE nosys
173 STD POSIX { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); }
174 STD POSIX { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); }
173 STD POSIX { ssize_t pread(int fd, void *buf, size_t nbyte, \
int pad, off_t offset); }
174 STD POSIX { ssize_t pwrite(int fd, const void *buf, \
size_t nbyte, int pad, off_t offset); }
175 UNIMPL NOHIDE nosys
176 STD BSD { int ntp_adjtime(struct timex *tp); }
177 UNIMPL NOHIDE sfork (BSD/OS 2.x)

View File

@ -13,7 +13,7 @@
* bad that happens because of using this software isn't the responsibility
* of the author. This software is distributed AS-IS.
*
* $Id: vfs_aio.c,v 1.43 1999/02/19 14:25:35 luoqi Exp $
* $Id: vfs_aio.c,v 1.44 1999/02/25 15:54:06 bde Exp $
*/
/*
@ -570,10 +570,10 @@ aio_process(struct aiocblist *aiocbe)
oublock_st = mycp->p_stats->p_ru.ru_oublock;
if (cb->aio_lio_opcode == LIO_READ) {
auio.uio_rw = UIO_READ;
error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred, FOF_OFFSET);
} else {
auio.uio_rw = UIO_WRITE;
error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred, FOF_OFFSET);
}
inblock_end = mycp->p_stats->p_ru.ru_inblock;
oublock_end = mycp->p_stats->p_ru.ru_oublock;
@ -1709,7 +1709,7 @@ aio_read(struct proc *p, struct aio_read_args *uap)
auio.uio_procp = p;
cnt = iocb.aio_nbytes;
error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred, FOF_OFFSET);
if (error &&
(auio.uio_resid != cnt) &&
(error == ERESTART || error == EINTR || error == EWOULDBLOCK))
@ -1775,7 +1775,7 @@ aio_write(struct proc *p, struct aio_write_args *uap)
auio.uio_procp = p;
cnt = iocb.aio_nbytes;
error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred, FOF_OFFSET);
if (error) {
if (auio.uio_resid != cnt) {
if (error == ERESTART || error == EINTR || error == EWOULDBLOCK)

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
* $Id: vfs_vnops.c,v 1.63 1999/01/30 12:21:49 phk Exp $
* $Id: vfs_vnops.c,v 1.64 1999/03/26 20:25:21 alc Exp $
*/
#include <sys/param.h>
@ -55,11 +55,11 @@ static int vn_closefile __P((struct file *fp, struct proc *p));
static int vn_ioctl __P((struct file *fp, u_long com, caddr_t data,
struct proc *p));
static int vn_read __P((struct file *fp, struct uio *uio,
struct ucred *cred));
struct ucred *cred, int flags));
static int vn_poll __P((struct file *fp, int events, struct ucred *cred,
struct proc *p));
static int vn_write __P((struct file *fp, struct uio *uio,
struct ucred *cred));
struct ucred *cred, int flags));
struct fileops vnops =
{ vn_read, vn_write, vn_ioctl, vn_poll, vn_closefile };
@ -272,10 +272,11 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p)
* File table vnode read routine.
*/
static int
vn_read(fp, uio, cred)
vn_read(fp, uio, cred, flags)
struct file *fp;
struct uio *uio;
struct ucred *cred;
int flags;
{
struct vnode *vp = (struct vnode *)fp->f_data;
struct proc *p = uio->uio_procp;
@ -289,7 +290,7 @@ vn_read(fp, uio, cred)
if (fp->f_flag & FNONBLOCK)
flag |= IO_NDELAY;
if (uio->uio_offset != -1) {
if (flags & FOF_OFFSET) {
error = VOP_READ(vp, uio, flag, cred);
goto out;
}
@ -335,10 +336,11 @@ vn_read(fp, uio, cred)
* File table vnode write routine.
*/
static int
vn_write(fp, uio, cred)
vn_write(fp, uio, cred, flags)
struct file *fp;
struct uio *uio;
struct ucred *cred;
int flags;
{
struct vnode *vp = (struct vnode *)fp->f_data;
struct proc *p = uio->uio_procp;
@ -353,7 +355,7 @@ vn_write(fp, uio, cred)
ioflag |= IO_SYNC;
VOP_LEASE(vp, p, cred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (uio->uio_offset != -1) {
if (flags & FOF_OFFSET) {
error = VOP_WRITE(vp, uio, ioflag, cred);
goto out;
}

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)file.h 8.3 (Berkeley) 1/9/95
* $Id: file.h,v 1.15 1997/11/23 10:43:36 bde Exp $
* $Id: file.h,v 1.16 1998/06/07 17:12:58 dfr Exp $
*/
#ifndef _SYS_FILE_H_
@ -65,9 +65,10 @@ struct file {
struct ucred *f_cred; /* credentials associated with descriptor */
struct fileops {
int (*fo_read) __P((struct file *fp, struct uio *uio,
struct ucred *cred));
struct ucred *cred, int flags));
int (*fo_write) __P((struct file *fp, struct uio *uio,
struct ucred *cred));
struct ucred *cred, int flags));
#define FOF_OFFSET 1
int (*fo_ioctl) __P((struct file *fp, u_long com,
caddr_t data, struct proc *p));
int (*fo_poll) __P((struct file *fp, int events,

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)socketvar.h 8.3 (Berkeley) 2/19/95
* $Id: socketvar.h,v 1.35 1999/01/31 09:40:14 bde Exp $
* $Id: socketvar.h,v 1.36 1999/02/01 21:16:31 newton Exp $
*/
#ifndef _SYS_SOCKETVAR_H_
@ -287,8 +287,10 @@ struct uio;
/*
* File operations on sockets.
*/
int soo_read __P((struct file *fp, struct uio *uio, struct ucred *cred));
int soo_write __P((struct file *fp, struct uio *uio, struct ucred *cred));
int soo_read __P((struct file *fp, struct uio *uio, struct ucred *cred,
int flags));
int soo_write __P((struct file *fp, struct uio *uio, struct ucred *cred,
int flags));
int soo_close __P((struct file *fp, struct proc *p));
int soo_ioctl __P((struct file *fp, u_long cmd, caddr_t data,
struct proc *p));