Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Mar 2011 02:59:24 +0200
From:      Kostik Belousov <kostikbel@gmail.com>
To:        fs@freebsd.org
Subject:   O_CLOEXEC
Message-ID:  <20110325005923.GI78089@deviant.kiev.zoral.com.ua>

next in thread | raw e-mail | index | archive | help

--uLnwevNQM8S3VmeD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi,
below is the implementation of O_CLOEXEC flag for open(2). I also
handle the fhopen(2), since the man page states that fhopen(2) takes
the same flags as open(2), and it is more logical to change code
then man page.

It is somewhat curious that SUSv4 did not specified O_CLOEXEC behaviour
for posix_openpt(). I left it out, but it probably makes sense to
allow O_CLOEXEC there ?

The falloc() KPI is left as is because the function is often used
in the kernel and probably in the third-party modules. fdallocf()
takes additional flag argument to set close-on-exec before any other
thread might see new file descriptor.

diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2
index deca8bc..e0f5fff 100644
--- a/lib/libc/sys/open.2
+++ b/lib/libc/sys/open.2
@@ -28,7 +28,7 @@
 .\"     @(#)open.2	8.2 (Berkeley) 11/16/93
 .\" $FreeBSD$
 .\"
-.Dd February 28, 2009
+.Dd March 25, 2011
 .Dt OPEN 2
 .Os
 .Sh NAME
@@ -118,6 +118,7 @@ O_NOFOLLOW	do not follow symlinks
 O_NOCTTY	don't assign controlling terminal
 O_TTY_INIT	restore default terminal attributes
 O_DIRECTORY	error if file is not a directory
+O_CLOEXEC	set FD_CLOEXEC upon open
 .Ed
 .Pp
 Opening a file with
@@ -231,6 +232,11 @@ from opening files which are even unsafe to open with
 .Dv O_RDONLY ,
 such as device nodes.
 .Pp
+.Dv O_CLOEXEC
+may be used to set
+.Dv FD_CLOEXEC
+flag for the newly returned file descriptor.
+.Pp
 If successful,
 .Fn open
 returns a non-negative integer, termed a file descriptor.
@@ -241,12 +247,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 a979368..21590d3 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1516,7 +1516,7 @@ fdavail(struct thread *td, int n)
  * release the FILEDESC lock.
  */
 int
-falloc(struct thread *td, struct file **resultfp, int *resultfd)
+fallocf(struct thread *td, struct file **resultfp, int *resultfd, int flag=
s)
 {
 	struct proc *p =3D td->td_proc;
 	struct file *fp;
@@ -1559,6 +1559,8 @@ falloc(struct thread *td, struct file **resultfp, int=
 *resultfd)
 		return (error);
 	}
 	p->p_fd->fd_ofiles[i] =3D fp;
+	if ((flags & O_CLOEXEC) !=3D 0)
+		p->p_fd->fd_ofileflags[i] |=3D UF_EXCLOSE;
 	FILEDESC_XUNLOCK(p->p_fd);
 	if (resultfp)
 		*resultfp =3D fp;
@@ -1567,6 +1569,13 @@ falloc(struct thread *td, struct file **resultfp, in=
t *resultfd)
 	return (0);
 }
=20
+int
+falloc(struct thread *td, struct file **resultfp, int *resultfd)
+{
+
+	return (fallocf(td, resultfp, resultfd, 0));
+}
+
 /*
  * Build a new filedesc structure from another.
  * Copy the current, root, and jail root vnode references.
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 9046d1c..fe66591 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1069,7 +1069,7 @@ kern_openat(struct thread *td, int fd, char *path, en=
um uio_seg pathseg,
 	else
 		flags =3D FFLAGS(flags);
=20
-	error =3D falloc(td, &nfp, &indx);
+	error =3D fallocf(td, &nfp, &indx, flags);
 	if (error)
 		return (error);
 	/* An extra reference on `nfp' has been held for us by falloc(). */
@@ -4488,7 +4488,7 @@ fhopen(td, uap)
 	 * end of vn_open code
 	 */
=20
-	if ((error =3D falloc(td, &nfp, &indx)) !=3D 0) {
+	if ((error =3D fallocf(td, &nfp, &indx, fmode)) !=3D 0) {
 		if (fmode & FWRITE)
 			vp->v_writecount--;
 		goto bad;
diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h
index ef394a3..6f6e348 100644
--- a/sys/sys/fcntl.h
+++ b/sys/sys/fcntl.h
@@ -123,9 +123,11 @@ typedef	__pid_t		pid_t;
 #define	FEXEC		O_EXEC
 #endif
=20
-/* Defined by POSIX 1003.1-2008; BSD default, but reserve for future use. =
*/
 #if __POSIX_VISIBLE >=3D 200809
+/* Defined by POSIX 1003.1-2008; BSD default, but reserve for future use. =
*/
 #define	O_TTY_INIT	0x00080000	/* Restore default termios attributes */
+
+#define	O_CLOEXEC	0x00100000
 #endif
=20
 /*
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index dd97d44..c96d6f9 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -112,6 +112,8 @@ int	closef(struct file *fp, struct thread *td);
 int	dupfdopen(struct thread *td, struct filedesc *fdp, int indx, int dfd,
 	    int mode, int error);
 int	falloc(struct thread *td, struct file **resultfp, int *resultfd);
+int	fallocf(struct thread *td, struct file **resultfp, int *resultfd,
+	    int flags);
 int	fdalloc(struct thread *td, int minfd, int *result);
 int	fdavail(struct thread *td, int n);
 int	fdcheckstd(struct thread *td);

--uLnwevNQM8S3VmeD
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (FreeBSD)

iEYEARECAAYFAk2L6OsACgkQC3+MBN1Mb4gmzgCg3i18tgBApyAs8ZORfcJ209PY
QckAoM6S26B80s5fHJTsMejzXlyLX/SY
=hSgT
-----END PGP SIGNATURE-----

--uLnwevNQM8S3VmeD--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110325005923.GI78089>