From 5fe6d89b7413bad9d81d0b715cf3b2b0c18089f7 Mon Sep 17 00:00:00 2001 From: Francois Tigeot Date: Wed, 25 Apr 2012 14:50:48 +0200 Subject: [PATCH] Add O_CLOEXEC flag to open(2) and fhopen(2) Inspired from: FreeBSD. --- lib/libc/sys/open.2 | 23 +++++++++++++++++------ sys/kern/kern_descrip.c | 10 +++++++++- sys/kern/vfs_syscalls.c | 4 ++-- sys/sys/fcntl.h | 1 + sys/sys/filedesc.h | 1 + 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2 index 2e0c634..9d4d0b3 100644 --- a/lib/libc/sys/open.2 +++ b/lib/libc/sys/open.2 @@ -30,10 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)open.2 8.2 (Berkeley) 11/16/93 -.\" $FreeBSD: src/lib/libc/sys/open.2,v 1.11.2.9 2001/12/14 18:34:01 ru Exp $ -.\" $DragonFly: src/lib/libc/sys/open.2,v 1.3 2005/07/29 23:16:04 hsu Exp $ +.\" $FreeBSD: src/lib/libc/sys/open.2,v 1.43 2011/03/25 14:01:18 kib Exp $ .\" -.Dd July 24, 2009 +.Dd March 25, 2011 .Dt OPEN 2 .Os .Sh NAME @@ -119,6 +118,7 @@ O_EXLOCK atomically obtain an exclusive lock O_DIRECT eliminate or reduce cache effects O_FSYNC synchronous writes O_NOFOLLOW do not follow symlinks +O_CLOEXEC set FD_CLOEXEC upon open .Ed .Pp Opening a file with @@ -193,6 +193,11 @@ If it cannot avoid caching the data, it will minimize the impact the data has on the cache. Use of this flag can drastically reduce performance if not used with care. .Pp +.Dv O_CLOEXEC +may be used to set +.Dv FD_CLOEXEC +flag for the newly returned file descriptor. +.Pp If successful, .Fn open and @@ -205,12 +210,18 @@ file is set to the beginning of the file. When a new file is created it is given the group of the directory which contains it. .Pp -The new descriptor is set to remain open across +Unless +.Dv +O_CLOEXEC +flag was specified, +the new descriptor is set to remain open across .Xr execve 2 system calls; see -.Xr close 2 +.Xr close 2 , +.Xr fcntl 2 and -.Xr fcntl 2 . +.Dv O_CLOEXEC +description. .Pp The system imposes a limit on the number of file descriptors open simultaneously by one process. diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index a967e33..d88831c 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1498,7 +1498,7 @@ fdrevoke_proc_callback(struct proc *p, void *vinfo) * MPSAFE */ int -falloc(struct lwp *lp, struct file **resultfp, int *resultfd) +fallocf(struct lwp *lp, struct file **resultfp, int *resultfd, int flags) { static struct timeval lastfail; static int curfail; @@ -1532,6 +1532,8 @@ falloc(struct lwp *lp, struct file **resultfp, int *resultfd) fp->f_ops = &badfileops; fp->f_seqcount = 1; fsetcred(fp, cred); + if ((flags & O_CLOEXEC) != 0) + fp->f_flag |= UF_EXCLOSE; spin_lock(&filehead_spin); nfiles++; LIST_INSERT_HEAD(&filehead, fp, f_list); @@ -1549,6 +1551,12 @@ done: return (error); } +int +falloc(struct lwp *lp, struct file **resultfp, int *resultfd) +{ + return fallocf(lp, resultfp, resultfd, 0); +} + /* * Check for races against a file descriptor by determining that the * file pointer is still associated with the specified file descriptor, diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 11c66a8..cabcebc 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1817,7 +1817,7 @@ kern_open(struct nlookupdata *nd, int oflags, int mode, int *res) if ((oflags & O_ACCMODE) == O_ACCMODE) return (EINVAL); flags = FFLAGS(oflags); - error = falloc(lp, &nfp, NULL); + error = fallocf(lp, &nfp, NULL, flags); if (error) return (error); fp = nfp; @@ -4218,7 +4218,7 @@ sys_fhopen(struct fhopen_args *uap) * WARNING! no f_nchandle will be associated when fhopen()ing a * directory. XXX */ - if ((error = falloc(td->td_lwp, &nfp, &indx)) != 0) + if ((error = fallocf(td->td_lwp, &nfp, &indx, fmode)) != 0) goto bad; fp = nfp; diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h index 353ab9b..4dd662e 100644 --- a/sys/sys/fcntl.h +++ b/sys/sys/fcntl.h @@ -93,6 +93,7 @@ /* Defined by POSIX 1003.1; BSD default, but must be distinct from O_RDONLY. */ #define O_NOCTTY 0x8000 /* don't assign controlling terminal */ +#define O_CLOEXEC 0x10000 /* atomically set FD_CLOEXEC */ /* Attempt to bypass the buffer cache */ #define O_DIRECT 0x00010000 diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 2be21d5..285671a 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -155,6 +155,7 @@ struct lwp; int dupfdopen (struct filedesc *, int, int, int, int); int fdalloc (struct proc *p, int want, int *result); int fdavail (struct proc *p, int n); +int fallocf(struct lwp *lp, struct file **resultfp, int *resultfd, int flags); int falloc (struct lwp *lp, struct file **resultfp, int *resultfd); void fsetfd (struct filedesc *fdp, struct file *fp, int fd); int fgetfdflags(struct filedesc *fdp, int fd, int *flagsp); -- 1.7.9.3