Module Name: src
Committed By: christos
Date: Sun Apr 10 15:45:34 UTC 2011
Modified Files:
src/sys/kern: kern_descrip.c sys_descrip.c sys_generic.c sys_pipe.c
uipc_syscalls.c vfs_syscalls.c
src/sys/sys: fcntl.h filedesc.h
Log Message:
- Add O_CLOEXEC to open(2)
- Add fd_set_exclose() to encapsulate uses of FIO{,N}CLEX, O_CLOEXEC, F{G,S}ETFD
- Add a pipe1() function to allow passing flags to the fd's that pipe(2)
opens to ease implementation of linux pipe2(2)
- Factor out fp handling code from open(2) and fhopen(2)
To generate a diff of this commit:
cvs rdiff -u -r1.211 -r1.212 src/sys/kern/kern_descrip.c
cvs rdiff -u -r1.19 -r1.20 src/sys/kern/sys_descrip.c
cvs rdiff -u -r1.125 -r1.126 src/sys/kern/sys_generic.c
cvs rdiff -u -r1.129 -r1.130 src/sys/kern/sys_pipe.c
cvs rdiff -u -r1.141 -r1.142 src/sys/kern/uipc_syscalls.c
cvs rdiff -u -r1.421 -r1.422 src/sys/kern/vfs_syscalls.c
cvs rdiff -u -r1.36 -r1.37 src/sys/sys/fcntl.h
cvs rdiff -u -r1.58 -r1.59 src/sys/sys/filedesc.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/kern_descrip.c
diff -u src/sys/kern/kern_descrip.c:1.211 src/sys/kern/kern_descrip.c:1.212
--- src/sys/kern/kern_descrip.c:1.211 Tue Feb 15 10:54:28 2011
+++ src/sys/kern/kern_descrip.c Sun Apr 10 11:45:33 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_descrip.c,v 1.211 2011/02/15 15:54:28 pooka Exp $ */
+/* $NetBSD: kern_descrip.c,v 1.212 2011/04/10 15:45:33 christos Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.211 2011/02/15 15:54:28 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.212 2011/04/10 15:45:33 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1776,6 +1776,16 @@
return error;
}
+void
+fd_set_exclose(struct lwp *l, int fd, bool exclose)
+{
+ filedesc_t *fdp = l->l_fd;
+ fdfile_t *ff = fdp->fd_dt->dt_ff[fd];
+ ff->ff_exclose = exclose;
+ if (exclose)
+ fdp->fd_exclose = true;
+}
+
/*
* Return descriptor owner information. If the value is positive,
* it's process ID. If it's negative, it's process group ID and
Index: src/sys/kern/sys_descrip.c
diff -u src/sys/kern/sys_descrip.c:1.19 src/sys/kern/sys_descrip.c:1.20
--- src/sys/kern/sys_descrip.c:1.19 Fri Dec 17 20:18:48 2010
+++ src/sys/kern/sys_descrip.c Sun Apr 10 11:45:33 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_descrip.c,v 1.19 2010/12/18 01:18:48 rmind Exp $ */
+/* $NetBSD: sys_descrip.c,v 1.20 2011/04/10 15:45:33 christos Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_descrip.c,v 1.19 2010/12/18 01:18:48 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_descrip.c,v 1.20 2011/04/10 15:45:33 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -315,7 +315,6 @@
int fd, i, tmp, error, cmd, newmin;
filedesc_t *fdp;
file_t *fp;
- fdfile_t *ff;
struct flock fl;
fd = SCARG(uap, fd);
@@ -358,7 +357,6 @@
if ((fp = fd_getfile(fd)) == NULL)
return (EBADF);
- ff = fdp->fd_dt->dt_ff[fd];
if ((cmd & F_FSCTL)) {
error = fcntl_forfs(fd, fp, cmd, SCARG(uap, arg));
@@ -380,16 +378,12 @@
break;
case F_GETFD:
- *retval = ff->ff_exclose;
+ *retval = fdp->fd_dt->dt_ff[fd]->ff_exclose;
break;
case F_SETFD:
- if ((long)SCARG(uap, arg) & FD_CLOEXEC) {
- ff->ff_exclose = true;
- fdp->fd_exclose = true;
- } else {
- ff->ff_exclose = false;
- }
+ fd_set_exclose(l, fd,
+ ((long)SCARG(uap, arg) & FD_CLOEXEC) != 0);
break;
case F_GETFL:
Index: src/sys/kern/sys_generic.c
diff -u src/sys/kern/sys_generic.c:1.125 src/sys/kern/sys_generic.c:1.126
--- src/sys/kern/sys_generic.c:1.125 Tue Jan 18 14:52:23 2011
+++ src/sys/kern/sys_generic.c Sun Apr 10 11:45:33 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_generic.c,v 1.125 2011/01/18 19:52:23 matt Exp $ */
+/* $NetBSD: sys_generic.c,v 1.126 2011/04/10 15:45:33 christos Exp $ */
/*-
* Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.125 2011/01/18 19:52:23 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.126 2011/04/10 15:45:33 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -522,20 +522,17 @@
} */
struct file *fp;
proc_t *p;
- struct filedesc *fdp;
u_long com;
int error;
size_t size, alloc_size;
void *data, *memp;
#define STK_PARAMS 128
u_long stkbuf[STK_PARAMS/sizeof(u_long)];
- fdfile_t *ff;
memp = NULL;
alloc_size = 0;
error = 0;
p = l->l_proc;
- fdp = p->p_fd;
if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
return (EBADF);
@@ -546,15 +543,10 @@
goto out;
}
- ff = fdp->fd_dt->dt_ff[SCARG(uap, fd)];
switch (com = SCARG(uap, com)) {
case FIONCLEX:
- ff->ff_exclose = false;
- goto out;
-
case FIOCLEX:
- ff->ff_exclose = true;
- fdp->fd_exclose = true;
+ fd_set_exclose(l, SCARG(uap, fd), com == FIOCLEX);
goto out;
}
Index: src/sys/kern/sys_pipe.c
diff -u src/sys/kern/sys_pipe.c:1.129 src/sys/kern/sys_pipe.c:1.130
--- src/sys/kern/sys_pipe.c:1.129 Mon Jan 17 02:13:32 2011
+++ src/sys/kern/sys_pipe.c Sun Apr 10 11:45:33 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_pipe.c,v 1.129 2011/01/17 07:13:32 uebayasi Exp $ */
+/* $NetBSD: sys_pipe.c,v 1.130 2011/04/10 15:45:33 christos Exp $ */
/*-
* Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.129 2011/01/17 07:13:32 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.130 2011/04/10 15:45:33 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -244,7 +244,7 @@
* The pipe system call for the DTYPE_PIPE type of pipes
*/
int
-sys_pipe(struct lwp *l, const void *v, register_t *retval)
+pipe1(struct lwp *l, register_t *retval, int flags)
{
struct pipe *rpipe, *wpipe;
file_t *rf, *wf;
@@ -266,7 +266,7 @@
if (error)
goto free2;
retval[0] = fd;
- rf->f_flag = FREAD;
+ rf->f_flag = FREAD | flags;
rf->f_type = DTYPE_PIPE;
rf->f_data = (void *)rpipe;
rf->f_ops = &pipeops;
@@ -275,7 +275,7 @@
if (error)
goto free3;
retval[1] = fd;
- wf->f_flag = FWRITE;
+ wf->f_flag = FWRITE | flags;
wf->f_type = DTYPE_PIPE;
wf->f_data = (void *)wpipe;
wf->f_ops = &pipeops;
@@ -295,6 +295,12 @@
return (error);
}
+int
+sys_pipe(struct lwp *l, const void *v, register_t *retval)
+{
+ return pipe1(l, retval, 0);
+}
+
/*
* Allocate kva for pipe circular buffer, the space is pageable
* This routine will 'realloc' the size of a pipe safely, if it fails
Index: src/sys/kern/uipc_syscalls.c
diff -u src/sys/kern/uipc_syscalls.c:1.141 src/sys/kern/uipc_syscalls.c:1.142
--- src/sys/kern/uipc_syscalls.c:1.141 Fri Apr 23 11:19:19 2010
+++ src/sys/kern/uipc_syscalls.c Sun Apr 10 11:45:33 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_syscalls.c,v 1.141 2010/04/23 15:19:19 rmind Exp $ */
+/* $NetBSD: uipc_syscalls.c,v 1.142 2011/04/10 15:45:33 christos Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.141 2010/04/23 15:19:19 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.142 2011/04/10 15:45:33 christos Exp $");
#include "opt_pipe.h"
@@ -960,7 +960,7 @@
#ifdef PIPE_SOCKETPAIR
/* ARGSUSED */
int
-sys_pipe(struct lwp *l, const void *v, register_t *retval)
+pipe1(struct lwp *l, register_t *retval, int flags)
{
file_t *rf, *wf;
struct socket *rso, *wso;
@@ -978,13 +978,13 @@
if ((error = fd_allocfile(&rf, &fd)) != 0)
goto free2;
retval[0] = fd;
- rf->f_flag = FREAD;
+ rf->f_flag = FREAD | flags;
rf->f_type = DTYPE_SOCKET;
rf->f_ops = &socketops;
rf->f_data = rso;
if ((error = fd_allocfile(&wf, &fd)) != 0)
goto free3;
- wf->f_flag = FWRITE;
+ wf->f_flag = FWRITE | flags;
wf->f_type = DTYPE_SOCKET;
wf->f_ops = &socketops;
wf->f_data = wso;
@@ -1007,6 +1007,12 @@
(void)soclose(rso);
return (error);
}
+
+int
+sys_pipe(struct lwp *l, const void *v, register_t *retval)
+{
+ return pipe1(l, retval, 0);
+}
#endif /* PIPE_SOCKETPAIR */
/*
Index: src/sys/kern/vfs_syscalls.c
diff -u src/sys/kern/vfs_syscalls.c:1.421 src/sys/kern/vfs_syscalls.c:1.422
--- src/sys/kern/vfs_syscalls.c:1.421 Sat Apr 2 00:57:35 2011
+++ src/sys/kern/vfs_syscalls.c Sun Apr 10 11:45:33 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_syscalls.c,v 1.421 2011/04/02 04:57:35 rmind Exp $ */
+/* $NetBSD: vfs_syscalls.c,v 1.422 2011/04/10 15:45:33 christos Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.421 2011/04/02 04:57:35 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.422 2011/04/10 15:45:33 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_fileassoc.h"
@@ -140,6 +140,45 @@
const int nmountcompatnames = __arraycount(mountcompatnames);
static int
+open_setfp(struct lwp *l, file_t *fp, struct vnode *vp, int indx, int flags)
+{
+ int error;
+
+ fp->f_flag = flags & FMASK;
+ fp->f_type = DTYPE_VNODE;
+ fp->f_ops = &vnops;
+ fp->f_data = vp;
+
+ if (flags & (O_EXLOCK | O_SHLOCK)) {
+ struct flock lf;
+ int type;
+
+ lf.l_whence = SEEK_SET;
+ lf.l_start = 0;
+ lf.l_len = 0;
+ if (flags & O_EXLOCK)
+ lf.l_type = F_WRLCK;
+ else
+ lf.l_type = F_RDLCK;
+ type = F_FLOCK;
+ if ((flags & FNONBLOCK) == 0)
+ type |= F_WAIT;
+ VOP_UNLOCK(vp);
+ error = VOP_ADVLOCK(vp, fp, F_SETLK, &lf, type);
+ if (error) {
+ (void) vn_close(vp, fp->f_flag, fp->f_cred);
+ fd_abort(l->l_proc, fp, indx);
+ return error;
+ }
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ atomic_or_uint(&fp->f_flag, FHASLOCK);
+ }
+ if (flags & O_CLOEXEC)
+ fd_set_exclose(l, indx, true);
+ return 0;
+}
+
+static int
mount_update(struct lwp *l, struct vnode *vp, const char *path, int flags,
void *data, size_t *data_len)
{
@@ -1039,8 +1078,7 @@
file_t *fp;
struct vnode *vp;
int flags, cmode;
- int type, indx, error;
- struct flock lf;
+ int indx, error;
struct pathbuf *pb;
struct nameidata nd;
@@ -1081,31 +1119,9 @@
vp = nd.ni_vp;
pathbuf_destroy(pb);
- fp->f_flag = flags & FMASK;
- fp->f_type = DTYPE_VNODE;
- fp->f_ops = &vnops;
- fp->f_data = vp;
- if (flags & (O_EXLOCK | O_SHLOCK)) {
- lf.l_whence = SEEK_SET;
- lf.l_start = 0;
- lf.l_len = 0;
- if (flags & O_EXLOCK)
- lf.l_type = F_WRLCK;
- else
- lf.l_type = F_RDLCK;
- type = F_FLOCK;
- if ((flags & FNONBLOCK) == 0)
- type |= F_WAIT;
- VOP_UNLOCK(vp);
- error = VOP_ADVLOCK(vp, fp, F_SETLK, &lf, type);
- if (error) {
- (void) vn_close(vp, fp->f_flag, fp->f_cred);
- fd_abort(p, fp, indx);
- return (error);
- }
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- atomic_or_uint(&fp->f_flag, FHASLOCK);
- }
+ if ((error = open_setfp(l, fp, vp, indx, flags)))
+ return error;
+
VOP_UNLOCK(vp);
*retval = indx;
fd_affix(p, fp, indx);
@@ -1362,8 +1378,7 @@
struct vnode *vp = NULL;
kauth_cred_t cred = l->l_cred;
file_t *nfp;
- int type, indx, error=0;
- struct flock lf;
+ int indx, error = 0;
struct vattr va;
fhandle_t *fh;
int flags;
@@ -1422,32 +1437,9 @@
}
/* done with modified vn_open, now finish what sys_open does. */
+ if ((error = open_setfp(l, fp, vp, indx, flags)))
+ return error;
- fp->f_flag = flags & FMASK;
- fp->f_type = DTYPE_VNODE;
- fp->f_ops = &vnops;
- fp->f_data = vp;
- if (flags & (O_EXLOCK | O_SHLOCK)) {
- lf.l_whence = SEEK_SET;
- lf.l_start = 0;
- lf.l_len = 0;
- if (flags & O_EXLOCK)
- lf.l_type = F_WRLCK;
- else
- lf.l_type = F_RDLCK;
- type = F_FLOCK;
- if ((flags & FNONBLOCK) == 0)
- type |= F_WAIT;
- VOP_UNLOCK(vp);
- error = VOP_ADVLOCK(vp, fp, F_SETLK, &lf, type);
- if (error) {
- (void) vn_close(vp, fp->f_flag, fp->f_cred);
- fd_abort(p, fp, indx);
- return (error);
- }
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- atomic_or_uint(&fp->f_flag, FHASLOCK);
- }
VOP_UNLOCK(vp);
*retval = indx;
fd_affix(p, fp, indx);
Index: src/sys/sys/fcntl.h
diff -u src/sys/sys/fcntl.h:1.36 src/sys/sys/fcntl.h:1.37
--- src/sys/sys/fcntl.h:1.36 Tue Sep 21 15:26:18 2010
+++ src/sys/sys/fcntl.h Sun Apr 10 11:45:33 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: fcntl.h,v 1.36 2010/09/21 19:26:18 chs Exp $ */
+/* $NetBSD: fcntl.h,v 1.37 2011/04/10 15:45:33 christos Exp $ */
/*-
* Copyright (c) 1983, 1990, 1993
@@ -113,6 +113,7 @@
#endif
#define O_DIRECTORY 0x00200000 /* fail if not a directory */
+#define O_CLOEXEC 0x00400000 /* set close on exec */
#ifdef _KERNEL
/* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE */
@@ -123,7 +124,7 @@
#define O_MASK (O_ACCMODE|O_NONBLOCK|O_APPEND|O_SHLOCK|O_EXLOCK|\
O_ASYNC|O_SYNC|O_CREAT|O_TRUNC|O_EXCL|O_DSYNC|\
O_RSYNC|O_NOCTTY|O_ALT_IO|O_NOFOLLOW|O_DIRECT|\
- O_DIRECTORY)
+ O_DIRECTORY|O_CLOEXEC)
#define FMARK 0x00001000 /* mark during gc() */
#define FDEFER 0x00002000 /* defer for next gc pass */
Index: src/sys/sys/filedesc.h
diff -u src/sys/sys/filedesc.h:1.58 src/sys/sys/filedesc.h:1.59
--- src/sys/sys/filedesc.h:1.58 Tue Feb 15 10:54:28 2011
+++ src/sys/sys/filedesc.h Sun Apr 10 11:45:33 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: filedesc.h,v 1.58 2011/02/15 15:54:28 pooka Exp $ */
+/* $NetBSD: filedesc.h,v 1.59 2011/04/10 15:45:33 christos Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -205,6 +205,8 @@
int fd_dup(file_t *, int, int *, bool);
int fd_dup2(file_t *, unsigned);
int fd_clone(file_t *, unsigned, int, const struct fileops *, void *);
+void fd_set_exclose(struct lwp *, int, bool);
+int pipe1(struct lwp *, register_t *, int);
void cwd_sys_init(void);
struct cwdinfo *cwdinit(void);