diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2009-08-21 09:36:14 +0200 |
---|---|---|
committer | Paolo Bonzini <bonzini@gnu.org> | 2009-08-21 14:05:25 +0200 |
commit | 4bd86a4de354c84ed23d3533feb649cf7de1e413 (patch) | |
tree | 32ca1e5ac7b2cb05c98161aa1b0552fb30ec6e85 /lib/popen-safer.c | |
parent | 2dce770482f30d1f07b3e99fd0d21b06f6e800fd (diff) | |
download | gnulib-4bd86a4de354c84ed23d3533feb649cf7de1e413.tar.gz |
popen-safer: test O_CLOEXEC at run-time.
* lib/popen-safer.c: Test O_CLOEXEC at run-time.
Diffstat (limited to 'lib/popen-safer.c')
-rw-r--r-- | lib/popen-safer.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/popen-safer.c b/lib/popen-safer.c index 1905be5ecb..3d87c28bb3 100644 --- a/lib/popen-safer.c +++ b/lib/popen-safer.c @@ -27,18 +27,28 @@ #include "cloexec.h" -#ifndef O_CLOEXEC -# define O_CLOEXEC 0 -#endif - /* Like open (name, flags | O_CLOEXEC), although not necessarily atomic. FLAGS must not include O_CREAT. */ static int open_noinherit (char const *name, int flags) { - int fd = open (name, flags | O_CLOEXEC); - if (0 <= fd && !O_CLOEXEC && set_cloexec_flag (fd, true) != 0) + int fd; +#ifdef O_CLOEXEC + /* 0 = unknown, 1 = yes, -1 = no. */ + static int have_cloexec; + if (have_cloexec >= 0) + { + fd = open (name, flags | O_CLOEXEC); + if (have_cloexec == 0 && (0 <= fd || errno == EINVAL)) + have_cloexec = (0 <= fd ? 1 : -1); + if (have_cloexec == 1) + return fd; + } +#endif + + fd = open (name, flags); + if (0 <= fd && set_cloexec_flag (fd, true) != 0) { int saved_errno = errno; close (fd); |