kern/169320: [libc] [patch] Enhancement to allow fopen() to set O_CLOEXEC for open()
Jilles Tjoelker
jilles at stack.nl
Wed Nov 7 22:20:02 UTC 2012
The following reply was made to PR kern/169320; it has been noted by GNATS.
From: Jilles Tjoelker <jilles at stack.nl>
To: bug-followup at FreeBSD.org, jau at iki.fi
Cc:
Subject: Re: kern/169320: [libc] [patch] Enhancement to allow fopen() to set
O_CLOEXEC for open()
Date: Wed, 7 Nov 2012 23:16:22 +0100
--bg08WKrSYDhXBjb5
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Although the new fopen() flag can be emulated via
open(O_CLOEXEC)/fdopen() as done in lib/libc/gen/fstab.c, I don't like
having that complication all over libc.
I have written a patch almost entirely from scratch, though. I think
blindly accepting any order restricts future possibilities too much
(perhaps we want to put key/value pairs in the mode string at some
point, for example) and not necessary. C11 is very clear that the 'x'
option must come after any '+' or 'b' options. I decided that the 'e'
option must come after any '+, 'b' or 'x' options.
I also added code to use the 'e' option for freopen() and fdopen().
--
Jilles Tjoelker
--bg08WKrSYDhXBjb5
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="stdio-cloexec.patch"
Index: lib/libc/stdio/fdopen.c
===================================================================
--- lib/libc/stdio/fdopen.c (revision 240561)
+++ lib/libc/stdio/fdopen.c (working copy)
@@ -77,6 +77,8 @@
errno = EINVAL;
return (NULL);
}
+ if ((oflags & O_CLOEXEC) && _fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
+ return (NULL);
if ((fp = __sfp()) == NULL)
return (NULL);
Index: lib/libc/stdio/flags.c
===================================================================
--- lib/libc/stdio/flags.c (revision 240561)
+++ lib/libc/stdio/flags.c (working copy)
@@ -97,6 +97,7 @@
/* 'x' means exclusive (fail if the file exists) */
if (*mode == 'x') {
+ mode++;
if (m == O_RDONLY) {
errno = EINVAL;
return (0);
@@ -104,6 +105,10 @@
o |= O_EXCL;
}
+ /* set close-on-exec */
+ if (*mode == 'e')
+ o |= O_CLOEXEC;
+
*optr = m | o;
return (ret);
}
Index: lib/libc/stdio/fopen.3
===================================================================
--- lib/libc/stdio/fopen.3 (revision 242460)
+++ lib/libc/stdio/fopen.3 (working copy)
@@ -97,6 +97,14 @@
causes the
.Fn fopen
call to fail if the file already exists.
+An optional
+.Dq Li e
+following the above
+causes the
+.Fn fopen
+call to set the
+.Dv FD_CLOEXEC
+flag on the underlying file descriptor.
.Pp
The
.Fa mode
@@ -144,6 +152,11 @@
The
.Dq Li x
mode option is ignored.
+If the
+.Dq Li e
+mode option is present, the
+.Dv FD_CLOEXEC
+flag is set, otherwise it remains unchanged.
When the stream is closed via
.Xr fclose 3 ,
.Fa fildes
@@ -271,7 +284,11 @@
with the exception of the
.Dq Li x
mode option which conforms to
-.St -isoC-2011 .
+.St -isoC-2011
+and the
+.Dq Li e
+mode option which does not conform to any standard
+but is also supported by glibc.
The
.Fn fdopen
function
Index: lib/libc/stdio/freopen.c
===================================================================
--- lib/libc/stdio/freopen.c (revision 240561)
+++ lib/libc/stdio/freopen.c (working copy)
@@ -194,7 +194,8 @@
* assume stderr is always fd STDERR_FILENO, even if being freopen'd.
*/
if (wantfd >= 0) {
- if (_dup2(f, wantfd) >= 0) {
+ if ((oflags & O_CLOEXEC ? _fcntl(f, F_DUP2FD_CLOEXEC, wantfd) :
+ _dup2(f, wantfd)) >= 0) {
(void)_close(f);
f = wantfd;
} else
--bg08WKrSYDhXBjb5--
More information about the freebsd-bugs
mailing list