Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 Nov 2012 22:20:01 GMT
From:      Jilles Tjoelker <jilles@stack.nl>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/169320: [libc] [patch] Enhancement to allow fopen() to set O_CLOEXEC for open()
Message-ID:  <201211072220.qA7MK1K5075434@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/169320; it has been noted by GNATS.

From: Jilles Tjoelker <jilles@stack.nl>
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--



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