From owner-svn-src-head@FreeBSD.ORG Fri Nov 30 23:51:35 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 5D33C806; Fri, 30 Nov 2012 23:51:34 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 066F18FC15; Fri, 30 Nov 2012 23:51:34 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qAUNpXPI079391; Fri, 30 Nov 2012 23:51:33 GMT (envelope-from jilles@svn.freebsd.org) Received: (from jilles@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qAUNpXtC079387; Fri, 30 Nov 2012 23:51:33 GMT (envelope-from jilles@svn.freebsd.org) Message-Id: <201211302351.qAUNpXtC079387@svn.freebsd.org> From: Jilles Tjoelker Date: Fri, 30 Nov 2012 23:51:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r243731 - head/lib/libc/stdio X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Nov 2012 23:51:35 -0000 Author: jilles Date: Fri Nov 30 23:51:33 2012 New Revision: 243731 URL: http://svnweb.freebsd.org/changeset/base/243731 Log: libc: Allow setting close-on-exec in fopen/freopen/fdopen. This commit adds a new mode option 'e' that must follow any 'b', '+' and/or 'x' options. C11 is clear about the 'x' needing to follow 'b' and/or '+' and that is what we implement; therefore, require a strict position for 'e' as well. For freopen() with a non-NULL path argument and fopen(), the close-on-exec flag is set iff the 'e' mode option is specified. For freopen() with a NULL path argument and fdopen(), the close-on-exec flag is turned on if the 'e' mode option is specified and remains unchanged otherwise. Although the same behaviour for fopen() can be obtained by open(O_CLOEXEC) and fdopen(), this needlessly complicates the calling code. Apart from the ordering requirement, the new option matches glibc. PR: kern/169320 Modified: head/lib/libc/stdio/fdopen.c head/lib/libc/stdio/flags.c head/lib/libc/stdio/fopen.3 head/lib/libc/stdio/freopen.c Modified: head/lib/libc/stdio/fdopen.c ============================================================================== --- head/lib/libc/stdio/fdopen.c Fri Nov 30 23:50:07 2012 (r243730) +++ head/lib/libc/stdio/fdopen.c Fri Nov 30 23:51:33 2012 (r243731) @@ -80,6 +80,12 @@ fdopen(fd, mode) if ((fp = __sfp()) == NULL) return (NULL); + + if ((oflags & O_CLOEXEC) && _fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) { + fp->_flags = 0; + return (NULL); + } + fp->_flags = flags; /* * If opened for appending, but underlying descriptor does not have Modified: head/lib/libc/stdio/flags.c ============================================================================== --- head/lib/libc/stdio/flags.c Fri Nov 30 23:50:07 2012 (r243730) +++ head/lib/libc/stdio/flags.c Fri Nov 30 23:51:33 2012 (r243731) @@ -97,6 +97,7 @@ __sflags(mode, optr) /* 'x' means exclusive (fail if the file exists) */ if (*mode == 'x') { + mode++; if (m == O_RDONLY) { errno = EINVAL; return (0); @@ -104,6 +105,10 @@ __sflags(mode, optr) o |= O_EXCL; } + /* set close-on-exec */ + if (*mode == 'e') + o |= O_CLOEXEC; + *optr = m | o; return (ret); } Modified: head/lib/libc/stdio/fopen.3 ============================================================================== --- head/lib/libc/stdio/fopen.3 Fri Nov 30 23:50:07 2012 (r243730) +++ head/lib/libc/stdio/fopen.3 Fri Nov 30 23:51:33 2012 (r243731) @@ -32,7 +32,7 @@ .\" @(#)fopen.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd October 17, 2011 +.Dd November 30, 2012 .Dt FOPEN 3 .Os .Sh NAME @@ -97,6 +97,14 @@ or 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 @@ of the stream must be compatible with th 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 @@ -277,3 +290,7 @@ The function conforms to .St -p1003.1-88 . +The +.Dq Li e +mode option does not conform to any standard +but is also supported by glibc. Modified: head/lib/libc/stdio/freopen.c ============================================================================== --- head/lib/libc/stdio/freopen.c Fri Nov 30 23:50:07 2012 (r243730) +++ head/lib/libc/stdio/freopen.c Fri Nov 30 23:51:33 2012 (r243731) @@ -118,6 +118,8 @@ freopen(file, mode, fp) (void) ftruncate(fp->_file, (off_t)0); if (!(oflags & O_APPEND)) (void) _sseek(fp, (fpos_t)0, SEEK_SET); + if (oflags & O_CLOEXEC) + (void) _fcntl(fp->_file, F_SETFD, FD_CLOEXEC); f = fp->_file; isopen = 0; wantfd = -1; @@ -194,7 +196,8 @@ finish: * 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