From owner-freebsd-bugs@FreeBSD.ORG Wed Nov 7 22:20:02 2012 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 36F201A6 for ; Wed, 7 Nov 2012 22:20:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) by mx1.freebsd.org (Postfix) with ESMTP id 1D0BC8FC08 for ; Wed, 7 Nov 2012 22:20:02 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id qA7MK1GW075435 for ; Wed, 7 Nov 2012 22:20:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id qA7MK1K5075434; Wed, 7 Nov 2012 22:20:01 GMT (envelope-from gnats) Date: Wed, 7 Nov 2012 22:20:01 GMT Message-Id: <201211072220.qA7MK1K5075434@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Jilles Tjoelker Subject: Re: kern/169320: [libc] [patch] Enhancement to allow fopen() to set O_CLOEXEC for open() X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: Jilles Tjoelker List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Nov 2012 22:20:02 -0000 The following reply was made to PR kern/169320; it has been noted by GNATS. From: Jilles Tjoelker To: bug-followup@FreeBSD.org, jau@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--