X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fpopen-safer.c;h=1791bc3b247735d0cb5d2177113257d624246ab5;hb=e240ab433593692f27c804c26ec1730a0dd27e5d;hp=1905be5ecbf898b079255f63d4629490a0d33b8e;hpb=2dce770482f30d1f07b3e99fd0d21b06f6e800fd;p=gnulib.git diff --git a/lib/popen-safer.c b/lib/popen-safer.c index 1905be5ec..1791bc3b2 100644 --- a/lib/popen-safer.c +++ b/lib/popen-safer.c @@ -1,6 +1,6 @@ /* Invoke popen, but avoid some glitches. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -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); @@ -75,7 +85,7 @@ popen_safer (char const *cmd, char const *mode) else { /* Either all fd's are tied up, or fd is safe and the real popen - will reuse it. */ + will reuse it. */ close (fd); fp = popen (cmd, mode); }