From 4bd86a4de354c84ed23d3533feb649cf7de1e413 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 21 Aug 2009 09:36:14 +0200 Subject: [PATCH] popen-safer: test O_CLOEXEC at run-time. * lib/popen-safer.c: Test O_CLOEXEC at run-time. --- ChangeLog | 5 +++++ lib/popen-safer.c | 22 ++++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index a1b015d03..565d70afa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2009-08-21 Paolo Bonzini + popen-safer: test O_CLOEXEC at run-time. + * lib/popen-safer.c: Test O_CLOEXEC at run-time. + +2009-08-21 Paolo Bonzini + fcntl: move more flags to the header * lib/cloexec.c: Do not define FD_CLOEXEC here. * lib/popen-safer.c: Do not alias O_NOINHERIT to O_CLOEXEC here. diff --git a/lib/popen-safer.c b/lib/popen-safer.c index 1905be5ec..3d87c28bb 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); -- 2.11.0