kern/169320: [libc] [patch] Enhancement to allow fopen() to set
O_CLOEXEC for open()
Jukka A. Ukkonen
jau at oxit.fi
Sun Jun 24 08:30:18 UTC 2012
The following reply was made to PR kern/169320; it has been noted by GNATS.
From: "Jukka A. Ukkonen" <jau at oxit.fi>
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: Sun, 24 Jun 2012 11:29:49 +0300
This is a multi-part message in MIME format.
--------------080303070506080801090202
Content-Type: multipart/alternative;
boundary="------------040105000505070101060901"
--------------040105000505070101060901
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Hmm... It seems linux and glibc-2.7 were there first...
*c* (since glibc 2.3.3)
Do not make the open operation, or subsequent read and write
operations, thread cancellation points.
*e* (since glibc 2.7)
Open the file with the*O_CLOEXEC* flag. See*open*(2) <http://www.freebsd.org/cgi/man.cgi?query=open&sektion=2&apropos=0&manpath=SuSE+Linux%2fi386+11.3> for more
information.
Should FreeBSD maybe follow the same pattern and use 'e' instead of 'c'
to force O_CLOEXEC for open()?
Personally I find 'e' a somewhat illogical linux-ism in contrast to 'c',
but because linux and glibc had already used 'c' those folks might be hard
to convince to change.
Active drive to heterogeneity would be unwise and only undermine emergence
of any decent standard.
Commercial vendors do not seem to support a similar feature yet, or they
have at least kept it undocumented.
So, I ended up creating a new revision of the patch.
(This one also properly uses relative paths.)
--jau
--------------040105000505070101060901
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<pre><tt>
Hmm... It seems linux and glibc-2.7 were there first...
<b>c</b> (since glibc 2.3.3)
Do not make the open operation, or subsequent read and write
operations, thread cancellation points.
<b>e</b> (since glibc 2.7)
Open the file with the <b>O_CLOEXEC</b> flag. See <a href="http://www.freebsd.org/cgi/man.cgi?query=open&sektion=2&apropos=0&manpath=SuSE+Linux%2fi386+11.3"><b>open</b>(2)</a> for more
information.
Should FreeBSD maybe follow the same pattern and use 'e' instead of 'c'
to force O_CLOEXEC for open()?
Personally I find 'e' a somewhat illogical linux-ism in contrast to 'c',
but because linux and glibc had already used 'c' those folks might be hard
to convince to change.
Active drive to heterogeneity would be unwise and only undermine emergence
of any decent standard.
Commercial vendors do not seem to support a similar feature yet, or they
have at least kept it undocumented.
So, I ended up creating a new revision of the patch.
(This one also properly uses relative paths.)
--jau
</tt></pre>
</body>
</html>
--------------040105000505070101060901--
--------------080303070506080801090202
Content-Type: text/plain; charset=UTF-8;
name="fopen-flags-CLOEXEC.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="fopen-flags-CLOEXEC.patch"
--- lib/libc/stdio/flags.c.orig 2012-01-09 06:59:44.000000000 +0200
+++ lib/libc/stdio/flags.c 2012-06-24 10:12:16.000000000 +0300
@@ -80,28 +80,43 @@
return (0);
}
- /* 'b' (binary) is ignored */
- if (*mode == 'b')
- mode++;
+ /*
+ * Because the order may not be universally deterministic,
+ * we are liberal and accept the add-on flags in any order.
+ */
- /* [rwa][b]\+ means read and write */
- if (*mode == '+') {
- mode++;
- ret = __SRW;
- m = O_RDWR;
- }
+ while (*mode) {
+ switch (*mode) {
+ case 'b':
+ /* 'b' (binary) is ignored */
+ break;
- /* 'b' (binary) can appear here, too -- and is ignored again */
- if (*mode == 'b')
- mode++;
+ case '+':
+ /* [rwa][b]\+ means read and write */
+ ret = __SRW;
+ m = O_RDWR;
+ break;
- /* 'x' means exclusive (fail if the file exists) */
- if (*mode == 'x') {
- if (m == O_RDONLY) {
- errno = EINVAL;
- return (0);
+ case 'x':
+ /* 'x' means exclusive (fail if the file exists) */
+ if (m == O_RDONLY) {
+ errno = EINVAL;
+ return (0);
+ }
+ o |= O_EXCL;
+ break;
+
+ case 'e':
+ /* Set the close-on-exec mark. */
+ o |= O_CLOEXEC;
+ break;
+
+ default:
+ /* We silently ignore what we do not know. */
+ break;
}
- o |= O_EXCL;
+
+ mode++;
}
*optr = m | o;
--- lib/libc/stdio/fopen.3.orig 2012-01-09 06:59:44.000000000 +0200
+++ lib/libc/stdio/fopen.3 2012-06-24 11:15:44.000000000 +0300
@@ -97,6 +97,12 @@
causes the
.Fn fopen
call to fail if the file already exists.
+The mode character
+.Dq Li x
+is a non-standard FreeBSD extension and a companion to the
+.Dq O_EXCL
+flag for
+.Fn open .
.Pp
The
.Fa mode
@@ -109,6 +115,29 @@
.St -isoC
and has no effect; the ``b'' is ignored.
.Pp
+If the
+.Fa mode
+string contains an optional character
+.Dq Li e
+the file will be automatically closed when
+.Fn exec
+is called.
+This is a non-standard FreeBSD extension and companion to the
+.Dq O_CLOEXEC
+flag for
+.Fn open .
+This is a handy tool for making code like system libraries more stable,
+but it also risks breaking the portability of code to other systems.
+There is no guarantee how other systems will handle a non-standard
+mode character.
+This implementation tries to be liberal and simply ignores all unknown
+mode characters.
+Linux knows both
+.Dq Li x
+and
+.Dq Li e
+mode characters and their semantics are similar to FreeBSD.
+.Pp
Any created files will have mode
.Do Dv S_IRUSR
\&|
--------------080303070506080801090202--
More information about the freebsd-bugs
mailing list