gettimeofday: port recent C++ fix to Emacs
[gnulib.git] / lib / popen-safer.c
index 1905be5..c493034 100644 (file)
@@ -1,6 +1,6 @@
 /* Invoke popen, but avoid some glitches.
 
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009-2013 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
 
 #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;
+#if 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);
     }