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);