and out.
Make pread/pwrite in netbsd & linux thread safe - which is the whole point
anyway.
-/* $OpenBSD: linux_file.c,v 1.11 2000/04/04 05:31:50 jasoni Exp $ */
+/* $OpenBSD: linux_file.c,v 1.12 2000/04/19 08:34:56 csapuntz Exp $ */
/* $NetBSD: linux_file.c,v 1.15 1996/05/20 01:59:09 fvdl Exp $ */
/*
static void linux_to_bsd_flock __P((struct linux_flock *, struct flock *));
static void bsd_to_linux_stat __P((struct stat *, struct linux_stat *));
static int linux_stat1 __P((struct proc *, void *, register_t *, int));
-static int linux_set_pos __P((struct proc *, int, off_t, off_t *));
+static int linux_set_pos __P((struct proc *, int, off_t));
/*
* sys_lseek trimmed down
*/
static int
-linux_set_pos(p, fd, offset, ooffset)
+linux_set_pos(p, fd, offset)
struct proc *p;
int fd;
off_t offset;
- off_t *ooffset;
{
register struct filedesc *fdp = p->p_fd;
register struct file *fp;
special = 0;
if (!special && offset < 0)
return (EINVAL);
- *ooffset = fp->f_offset;
- fp->f_offset = offset;
return (0);
}
struct uio auio;
struct iovec aiov;
long cnt, error = 0;
- off_t save_offset;
+ off_t offset;
/* Don't allow nbyte to be larger than max return val */
if (SCARG(uap, nbyte) > SSIZE_MAX)
return(EINVAL);
- if ((error = linux_set_pos(p, SCARG(uap, fd), SCARG(uap, offset),
- &save_offset)))
+
+ offset = SCARG(uap, offset);
+
+ if ((error = linux_set_pos(p, SCARG(uap, fd), offset)) != 0)
return (error);
+
fp = fdp->fd_ofiles[SCARG(uap, fd)];
aiov.iov_base = (caddr_t)SCARG(uap, buf);
aiov.iov_len = SCARG(uap, nbyte);
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
cnt = SCARG(uap, nbyte);
- error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_read)(fp, &offset, &auio, fp->f_cred);
if (error)
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
cnt -= auio.uio_resid;
- fp->f_offset = save_offset;
*retval = cnt;
return (error);
}
struct uio auio;
struct iovec aiov;
long cnt, error = 0;
- off_t save_offset;
+ off_t offset;
/* Don't allow nbyte to be larger than max return val */
if (SCARG(uap, nbyte) > SSIZE_MAX)
return(EINVAL);
- if ((error = linux_set_pos(p, SCARG(uap, fd), SCARG(uap, offset),
- &save_offset)))
+
+ offset = SCARG(uap, offset);
+
+ if ((error = linux_set_pos(p, SCARG(uap, fd), offset)) != 0)
return (error);
fp = fdp->fd_ofiles[SCARG(uap, fd)];
- if ((fp->f_flag & FWRITE) == 0) {
- fp->f_offset = save_offset;
+ if ((fp->f_flag & FWRITE) == 0)
return (EBADF);
- }
+
aiov.iov_base = (caddr_t)SCARG(uap, buf);
aiov.iov_len = SCARG(uap, nbyte);
auio.uio_iov = &aiov;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
cnt = SCARG(uap, nbyte);
- error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_write)(fp, &offset, &auio, fp->f_cred);
if (error) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
}
cnt -= auio.uio_resid;
*retval = cnt;
- fp->f_offset = save_offset;
return (error);
}
-/* $OpenBSD: netbsd_pos_io.c,v 1.4 1999/09/17 17:52:13 kstailey Exp $ */
+/* $OpenBSD: netbsd_pos_io.c,v 1.5 2000/04/19 08:34:57 csapuntz Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
#include <compat/netbsd/netbsd_signal.h>
#include <compat/netbsd/netbsd_syscallargs.h>
-static int netbsd_set_pos __P((struct proc *, int, off_t, off_t *));
+static int netbsd_check_set_pos __P((struct proc *, int, off_t));
/*
* sys_lseek trimmed down
*/
static int
-netbsd_set_pos(p, fd, offset, ooffset)
+netbsd_check_set_pos(p, fd)
struct proc *p;
int fd;
off_t offset;
- off_t *ooffset;
{
register struct filedesc *fdp = p->p_fd;
register struct file *fp;
special = 0;
if (!special && offset < 0)
return (EINVAL);
- *ooffset = fp->f_offset;
- fp->f_offset = offset;
return (0);
}
struct uio auio;
struct iovec aiov;
long cnt, error = 0;
- off_t save_offset;
+ off_t offset;
#ifdef KTRACE
struct iovec ktriov;
#endif
/* Don't allow nbyte to be larger than max return val */
if (SCARG(uap, nbyte) > SSIZE_MAX)
return(EINVAL);
- if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset),
- &save_offset)))
+
+ offset = SCARG(uap, offset);
+
+ if ((error = netbsd_check_set_pos(p, SCARG(uap, fd), offset) != 0)
return (error);
fp = fdp->fd_ofiles[SCARG(uap, fd)];
aiov.iov_base = (caddr_t)SCARG(uap, buf);
ktriov = aiov;
#endif
cnt = SCARG(uap, nbyte);
- error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_read)(fp, &offset, &auio, fp->f_cred);
if (error)
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, &ktriov,
cnt, error);
#endif
- fp->f_offset = save_offset;
*retval = cnt;
return (error);
}
struct iovec aiov[UIO_SMALLIOV];
long i, cnt, error = 0;
u_int iovlen;
- off_t save_offset;
+ off_t offset;
#ifdef KTRACE
struct iovec *ktriov = NULL;
#endif
if (SCARG(uap, iovcnt) <= 0)
return (EINVAL);
- if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset),
- &save_offset)))
+
+ offset = SCARG(uap, offset);
+
+ if ((error = netbsd_check_set_pos(p, SCARG(uap, fd), offset) != 0)
return (error);
fp = fdp->fd_ofiles[SCARG(uap, fd)];
/* 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) {
- fp->f_offset = save_offset;
return (EINVAL);
}
MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
}
#endif
cnt = auio.uio_resid;
- error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_read)(fp, &offset, &auio, fp->f_cred);
if (error)
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
done:
if (needfree)
FREE(needfree, M_IOV);
- fp->f_offset = save_offset;
return (error);
}
struct uio auio;
struct iovec aiov;
long cnt, error = 0;
- off_t save_offset;
+ off_t offset;
#ifdef KTRACE
struct iovec ktriov;
#endif
/* Don't allow nbyte to be larger than max return val */
if (SCARG(uap, nbyte) > SSIZE_MAX)
return(EINVAL);
- if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset),
- &save_offset)))
+
+ offset = SCARG(uap, offset);
+
+ if ((error = netbsd_check_set_pos(p, SCARG(uap, fd), offset) != 0)
return (error);
fp = fdp->fd_ofiles[SCARG(uap, fd)];
- if ((fp->f_flag & FWRITE) == 0) {
- fp->f_offset = save_offset;
+ if ((fp->f_flag & FWRITE) == 0)
return (EBADF);
- }
+
aiov.iov_base = (caddr_t)SCARG(uap, buf);
aiov.iov_len = SCARG(uap, nbyte);
auio.uio_iov = &aiov;
ktriov = aiov;
#endif
cnt = SCARG(uap, nbyte);
- error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_write)(fp, &offset, &auio, fp->f_cred);
if (error) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
&ktriov, cnt, error);
#endif
*retval = cnt;
- fp->f_offset = save_offset;
return (error);
}
struct iovec aiov[UIO_SMALLIOV];
long i, cnt, error = 0;
u_int iovlen;
- off_t save_offset;
+ off_t offset;
#ifdef KTRACE
struct iovec *ktriov = NULL;
#endif
if (SCARG(uap, iovcnt) <= 0)
return (EINVAL);
- if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset),
- &save_offset)))
+
+ offset = SCARG(uap, offset);
+
+ if ((error = netbsd_check_set_pos(p, SCARG(uap, fd), offset) != 0)
return (error);
fp = fdp->fd_ofiles[SCARG(uap, fd)];
if ((fp->f_flag & FWRITE) == 0) {
}
#endif
cnt = auio.uio_resid;
- error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_write)(fp, &offset, &auio, fp->f_cred);
if (error) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
#endif
*retval = cnt;
done:
- fp->f_offset = save_offset;
if (needfree)
FREE(needfree, M_IOV);
return (error);
-/* $OpenBSD: sys_generic.c,v 1.22 1999/11/29 22:02:14 deraadt Exp $ */
+/* $OpenBSD: sys_generic.c,v 1.23 2000/04/19 08:34:54 csapuntz Exp $ */
/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
/*
ktriov = aiov;
#endif
cnt = SCARG(uap, nbyte);
- error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_read)(fp, &fp->f_offset, &auio, fp->f_cred);
if (error)
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
}
#endif
cnt = auio.uio_resid;
- error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_read)(fp, &fp->f_offset, &auio, fp->f_cred);
if (error)
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
ktriov = aiov;
#endif
cnt = SCARG(uap, nbyte);
- error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_write)(fp, &fp->f_offset, &auio, fp->f_cred);
if (error) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
}
#endif
cnt = auio.uio_resid;
- error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
+ error = (*fp->f_ops->fo_write)(fp, &fp->f_offset, &auio, fp->f_cred);
if (error) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
-/* $OpenBSD: sys_pipe.c,v 1.23 2000/01/27 18:56:13 art Exp $ */
+/* $OpenBSD: sys_pipe.c,v 1.24 2000/04/19 08:34:54 csapuntz Exp $ */
/*
* Copyright (c) 1996 John S. Dyson
/*
* interfaces to the outside world
*/
-int pipe_read __P((struct file *, struct uio *, struct ucred *));
-int pipe_write __P((struct file *, struct uio *, struct ucred *));
+int pipe_read __P((struct file *, off_t *, struct uio *, struct ucred *));
+int pipe_write __P((struct file *, off_t *, struct uio *, struct ucred *));
int pipe_close __P((struct file *, struct proc *));
int pipe_select __P((struct file *, int which, struct proc *));
int pipe_ioctl __P((struct file *, u_long, caddr_t, struct proc *));
/* ARGSUSED */
int
-pipe_read(fp, uio, cred)
+pipe_read(fp, poff, uio, cred)
struct file *fp;
+ off_t *poff;
struct uio *uio;
struct ucred *cred;
{
}
int
-pipe_write(fp, uio, cred)
+pipe_write(fp, poff, uio, cred)
struct file *fp;
+ off_t *poff;
struct uio *uio;
struct ucred *cred;
{
-/* $OpenBSD: sys_socket.c,v 1.3 1997/08/31 20:42:23 deraadt Exp $ */
+/* $OpenBSD: sys_socket.c,v 1.4 2000/04/19 08:34:53 csapuntz Exp $ */
/* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */
/*
/* ARGSUSED */
int
-soo_read(fp, uio, cred)
+soo_read(fp, poff, uio, cred)
struct file *fp;
+ off_t *poff;
struct uio *uio;
struct ucred *cred;
{
/* ARGSUSED */
int
-soo_write(fp, uio, cred)
+soo_write(fp, poff, uio, cred)
struct file *fp;
+ off_t *poff;
struct uio *uio;
struct ucred *cred;
{
-/* $OpenBSD: vfs_vnops.c,v 1.23 1999/11/13 03:48:09 angelos Exp $ */
+/* $OpenBSD: vfs_vnops.c,v 1.24 2000/04/19 08:34:53 csapuntz Exp $ */
/* $NetBSD: vfs_vnops.c,v 1.20 1996/02/04 02:18:41 christos Exp $ */
/*
#include <uvm/uvm_extern.h>
#endif
+int vn_read __P((struct file *fp, off_t *off, struct uio *uio,
+ struct ucred *cred));
+int vn_write __P((struct file *fp, off_t *off, struct uio *uio,
+ struct ucred *cred));
+int vn_select __P((struct file *fp, int which, struct proc *p));
+int vn_closefile __P((struct file *fp, struct proc *p));
+int vn_ioctl __P((struct file *fp, u_long com, caddr_t data,
+ struct proc *p));
+
struct fileops vnops =
{ vn_read, vn_write, vn_ioctl, vn_select, vn_closefile };
* File table vnode read routine.
*/
int
-vn_read(fp, uio, cred)
+vn_read(fp, poff, uio, cred)
struct file *fp;
+ off_t *poff;
struct uio *uio;
struct ucred *cred;
{
VOP_LEASE(vp, uio->uio_procp, cred, LEASE_READ);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
- uio->uio_offset = fp->f_offset;
+ uio->uio_offset = *poff;
count = uio->uio_resid;
if (vp->v_type != VDIR)
error = VOP_READ(vp, uio,
(fp->f_flag & FNONBLOCK) ? IO_NDELAY : 0, cred);
- fp->f_offset += count - uio->uio_resid;
+ *poff += count - uio->uio_resid;
VOP_UNLOCK(vp, 0, p);
return (error);
}
* File table vnode write routine.
*/
int
-vn_write(fp, uio, cred)
+vn_write(fp, poff, uio, cred)
struct file *fp;
+ off_t *poff;
struct uio *uio;
struct ucred *cred;
{
ioflag |= IO_SYNC;
VOP_LEASE(vp, uio->uio_procp, cred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
- uio->uio_offset = fp->f_offset;
+ uio->uio_offset = *poff;
count = uio->uio_resid;
error = VOP_WRITE(vp, uio, ioflag, cred);
if (ioflag & IO_APPEND)
- fp->f_offset = uio->uio_offset;
+ *poff = uio->uio_offset;
else
- fp->f_offset += count - uio->uio_resid;
+ *poff += count - uio->uio_resid;
VOP_UNLOCK(vp, 0, p);
return (error);
}
if (com == FIBMAP)
return VOP_IOCTL(vp, com, data, fp->f_flag,
p->p_ucred, p);
- if (com == FIONBIO || com == FIOASYNC) /* XXX */
- return (0); /* XXX */
- /* fall into ... */
+ if (com == FIONBIO || com == FIOASYNC) /* XXX */
+ return (0); /* XXX */
+ /* fall into... */
default:
return (ENOTTY);
-
+
case VFIFO:
case VCHR:
case VBLK:
-/* $OpenBSD: file.h,v 1.5 2000/02/01 04:00:50 assar Exp $ */
+/* $OpenBSD: file.h,v 1.6 2000/04/19 08:34:50 csapuntz Exp $ */
/* $NetBSD: file.h,v 1.11 1995/03/26 20:24:13 jtc Exp $ */
/*
long f_msgcount; /* references from message queue */
struct ucred *f_cred; /* credentials associated with descriptor */
struct fileops {
- int (*fo_read) __P((struct file *fp, struct uio *uio,
- struct ucred *cred));
- int (*fo_write) __P((struct file *fp, struct uio *uio,
- struct ucred *cred));
+ int (*fo_read) __P((struct file *fp, off_t *,
+ struct uio *uio,
+ struct ucred *cred));
+ int (*fo_write) __P((struct file *fp, off_t *,
+ struct uio *uio,
+ struct ucred *cred));
int (*fo_ioctl) __P((struct file *fp, u_long com,
caddr_t data, struct proc *p));
int (*fo_select) __P((struct file *fp, int which,
-/* $OpenBSD: socketvar.h,v 1.17 1999/12/08 06:50:24 itojun Exp $ */
+/* $OpenBSD: socketvar.h,v 1.18 2000/04/19 08:34:51 csapuntz Exp $ */
/* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */
/*-
/*
* 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, off_t *, struct uio *uio,
+ struct ucred *cred));
+int soo_write __P((struct file *fp, off_t *, struct uio *uio,
+ struct ucred *cred));
int soo_ioctl __P((struct file *fp, u_long cmd, caddr_t data,
struct proc *p));
int soo_select __P((struct file *fp, int which, struct proc *p));
-/* $OpenBSD: vnode.h,v 1.22 1999/12/05 07:19:28 art Exp $ */
+/* $OpenBSD: vnode.h,v 1.23 2000/04/19 08:34:51 csapuntz Exp $ */
/* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */
/*
void vn_update __P((void));
int vn_close __P((struct vnode *vp,
int flags, struct ucred *cred, struct proc *p));
-int vn_closefile __P((struct file *fp, struct proc *p));
-int vn_ioctl __P((struct file *fp, u_long com, caddr_t data,
- struct proc *p));
int vn_open __P((struct nameidata *ndp, int fmode, int cmode));
int vrecycle __P((struct vnode *vp, struct simplelock *inter_lkp,
struct proc *p));
int vop_generic_unlock __P((void *));
int vop_generic_revoke __P((void *));
-int vn_read __P((struct file *fp, struct uio *uio, struct ucred *cred));
-int vn_select __P((struct file *fp, int which, struct proc *p));
int vn_stat __P((struct vnode *vp, struct stat *sb, struct proc *p));
-int vn_write __P((struct file *fp, struct uio *uio, struct ucred *cred));
int vn_writechk __P((struct vnode *vp));
void vn_syncer_add_to_worklist __P((struct vnode *vp, int delay));
void sched_sync __P((struct proc *));