Add the O_CLOFORK flag to open(2) and dup3(2) to automatically set the close-on-fork flag in the new file descriptor, saving a separate call to fcntl(2). Co-developed-by: Changli Gao <xiaosuo@xxxxxxxxx> Signed-off-by: Changli Gao <xiaosuo@xxxxxxxxx> Signed-off-by: Nate Karstens <nate.karstens@xxxxxxxxxx> --- arch/alpha/include/uapi/asm/fcntl.h | 2 ++ arch/parisc/include/uapi/asm/fcntl.h | 39 +++++++++++++------------- arch/sparc/include/uapi/asm/fcntl.h | 1 + fs/fcntl.c | 2 +- fs/file.c | 10 ++++++- include/linux/fcntl.h | 2 +- include/uapi/asm-generic/fcntl.h | 4 +++ tools/include/uapi/asm-generic/fcntl.h | 4 +++ 8 files changed, 42 insertions(+), 22 deletions(-) diff --git a/arch/alpha/include/uapi/asm/fcntl.h b/arch/alpha/include/uapi/asm/fcntl.h index 50bdc8e8a271..fbab69b15f7f 100644 --- a/arch/alpha/include/uapi/asm/fcntl.h +++ b/arch/alpha/include/uapi/asm/fcntl.h @@ -35,6 +35,8 @@ #define O_PATH 040000000 #define __O_TMPFILE 0100000000 +#define O_CLOFORK 0200000000 /* set close_on_fork */ + #define F_GETLK 7 #define F_SETLK 8 #define F_SETLKW 9 diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h index 03ce20e5ad7d..8f5989e75b05 100644 --- a/arch/parisc/include/uapi/asm/fcntl.h +++ b/arch/parisc/include/uapi/asm/fcntl.h @@ -2,26 +2,27 @@ #ifndef _PARISC_FCNTL_H #define _PARISC_FCNTL_H -#define O_APPEND 000000010 -#define O_BLKSEEK 000000100 /* HPUX only */ -#define O_CREAT 000000400 /* not fcntl */ -#define O_EXCL 000002000 /* not fcntl */ -#define O_LARGEFILE 000004000 -#define __O_SYNC 000100000 +#define O_APPEND 0000000010 +#define O_BLKSEEK 0000000100 /* HPUX only */ +#define O_CREAT 0000000400 /* not fcntl */ +#define O_EXCL 0000002000 /* not fcntl */ +#define O_LARGEFILE 0000004000 +#define __O_SYNC 0000100000 #define O_SYNC (__O_SYNC|O_DSYNC) -#define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ -#define O_NOCTTY 000400000 /* not fcntl */ -#define O_DSYNC 001000000 /* HPUX only */ -#define O_RSYNC 002000000 /* HPUX only */ -#define O_NOATIME 004000000 -#define O_CLOEXEC 010000000 /* set close_on_exec */ - -#define O_DIRECTORY 000010000 /* must be a directory */ -#define O_NOFOLLOW 000000200 /* don't follow links */ -#define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */ - -#define O_PATH 020000000 -#define __O_TMPFILE 040000000 +#define O_NONBLOCK 0000200004 /* HPUX has separate NDELAY & NONBLOCK */ +#define O_NOCTTY 0000400000 /* not fcntl */ +#define O_DSYNC 0001000000 /* HPUX only */ +#define O_RSYNC 0002000000 /* HPUX only */ +#define O_NOATIME 0004000000 +#define O_CLOEXEC 0010000000 /* set close_on_exec */ + +#define O_DIRECTORY 0000010000 /* must be a directory */ +#define O_NOFOLLOW 0000000200 /* don't follow links */ +#define O_INVISIBLE 0004000000 /* invisible I/O, for DMAPI/XDSM */ + +#define O_PATH 0020000000 +#define __O_TMPFILE 0040000000 +#define O_CLOFORK 0100000000 #define F_GETLK64 8 #define F_SETLK64 9 diff --git a/arch/sparc/include/uapi/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h index 67dae75e5274..d631ea13bac3 100644 --- a/arch/sparc/include/uapi/asm/fcntl.h +++ b/arch/sparc/include/uapi/asm/fcntl.h @@ -37,6 +37,7 @@ #define O_PATH 0x1000000 #define __O_TMPFILE 0x2000000 +#define O_CLOFORK 0x4000000 #define F_GETOWN 5 /* for sockets. */ #define F_SETOWN 6 /* for sockets. */ diff --git a/fs/fcntl.c b/fs/fcntl.c index 913b0cb70804..40af2a48702b 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -1033,7 +1033,7 @@ static int __init fcntl_init(void) * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY * is defined as O_NONBLOCK on some platforms and not on others. */ - BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ != + BUILD_BUG_ON(22 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( (VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) | __FMODE_EXEC | __FMODE_NONOTIFY)); diff --git a/fs/file.c b/fs/file.c index 81194349e980..4a1b84eecec6 100644 --- a/fs/file.c +++ b/fs/file.c @@ -547,6 +547,10 @@ int __alloc_fd(struct files_struct *files, __set_close_on_exec(fd, fdt); else __clear_close_on_exec(fd, fdt); + if (flags & O_CLOFORK) + __set_close_on_fork(fd, fdt); + else + __clear_close_on_fork(fd, fdt); error = fd; #if 1 /* Sanity check */ @@ -953,6 +957,10 @@ __releases(&files->file_lock) __set_close_on_exec(fd, fdt); else __clear_close_on_exec(fd, fdt); + if (flags & O_CLOFORK) + __set_close_on_fork(fd, fdt); + else + __clear_close_on_fork(fd, fdt); spin_unlock(&files->file_lock); if (tofree) @@ -993,7 +1001,7 @@ static int ksys_dup3(unsigned int oldfd, unsigned int newfd, int flags) struct file *file; struct files_struct *files = current->files; - if ((flags & ~O_CLOEXEC) != 0) + if ((flags & ~(O_CLOEXEC | O_CLOFORK)) != 0) return -EINVAL; if (unlikely(oldfd == newfd)) diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h index 7bcdcf4f6ab2..cd4c625647db 100644 --- a/include/linux/fcntl.h +++ b/include/linux/fcntl.h @@ -10,7 +10,7 @@ (O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | \ O_APPEND | O_NDELAY | O_NONBLOCK | O_NDELAY | __O_SYNC | O_DSYNC | \ FASYNC | O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \ - O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE) + O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE | O_CLOFORK) /* List of all valid flags for the how->upgrade_mask argument: */ #define VALID_UPGRADE_FLAGS \ diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h index 0cb7199a7743..165a0736a3aa 100644 --- a/include/uapi/asm-generic/fcntl.h +++ b/include/uapi/asm-generic/fcntl.h @@ -89,6 +89,10 @@ #define __O_TMPFILE 020000000 #endif +#ifndef O_CLOFORK +#define O_CLOFORK 040000000 /* set close_on_fork */ +#endif + /* a horrid kludge trying to make sure that this will fail on old kernels */ #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) #define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT) diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h index e04a00fecb4a..69d8a000ec65 100644 --- a/tools/include/uapi/asm-generic/fcntl.h +++ b/tools/include/uapi/asm-generic/fcntl.h @@ -88,6 +88,10 @@ #define __O_TMPFILE 020000000 #endif +#ifndef O_CLOFORK +#define O_CLOFORK 040000000 /* set close_on_fork */ +#endif + /* a horrid kludge trying to make sure that this will fail on old kernels */ #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) #define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT) -- 2.26.1