NEWS.stable: log cherry-pick [e446f25]->[c092018] relocatable-shell: Update suggested...
[gnulib.git] / lib / cloexec.c
index 57e0be5..48a0c97 100644 (file)
@@ -1,7 +1,6 @@
 /* closexec.c - set or clear the close-on-exec descriptor flag
 
-   Copyright (C) 1991, 2004, 2005, 2006, 2009 Free Software
-   Foundation, Inc.
+   Copyright (C) 1991, 2004-2006, 2009-2014 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 <fcntl.h>
 #include <unistd.h>
 
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-/* Native Woe32 API.  */
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# include <io.h>
-#endif
-
-
-/* Set the `FD_CLOEXEC' flag of DESC if VALUE is true,
+/* Set the 'FD_CLOEXEC' flag of DESC if VALUE is true,
    or clear the flag if VALUE is false.
-   Return 0 on success, or -1 on error with `errno' set.
+   Return 0 on success, or -1 on error with 'errno' set.
 
    Note that on MingW, this function does NOT protect DESC from being
    inherited into spawned children.  Instead, either use dup_cloexec
@@ -47,7 +38,7 @@
 int
 set_cloexec_flag (int desc, bool value)
 {
-#if defined F_GETFD && defined F_SETFD
+#ifdef F_SETFD
 
   int flags = fcntl (desc, F_GETFD, 0);
 
@@ -62,7 +53,7 @@ set_cloexec_flag (int desc, bool value)
 
   return -1;
 
-#else
+#else /* !F_SETFD */
 
   /* Use dup2 to reject invalid file descriptors; the cloexec flag
      will be unaffected.  */
@@ -71,9 +62,13 @@ set_cloexec_flag (int desc, bool value)
       errno = EBADF;
       return -1;
     }
-  return dup2 (desc, desc) == desc ? 0 : -1;
+  if (dup2 (desc, desc) < 0)
+    /* errno is EBADF here.  */
+    return -1;
 
-#endif
+  /* There is nothing we can do on this kind of platform.  Punt.  */
+  return 0;
+#endif /* !F_SETFD */
 }
 
 
@@ -84,77 +79,5 @@ set_cloexec_flag (int desc, bool value)
 int
 dup_cloexec (int fd)
 {
-  int nfd;
-
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-
-  /* Native Woe32 API.  */
-  HANDLE curr_process = GetCurrentProcess ();
-  HANDLE old_handle = (HANDLE) _get_osfhandle (fd);
-  HANDLE new_handle;
-  int mode;
-
-  if (old_handle == INVALID_HANDLE_VALUE
-      || (mode = setmode (fd, O_BINARY)) == -1)
-    {
-      /* fd is closed, or is open to no handle at all.
-         We cannot duplicate fd in this case, because _open_osfhandle
-         fails for an INVALID_HANDLE_VALUE argument.  */
-      errno = EBADF;
-      return -1;
-    }
-  setmode (fd, mode);
-
-  if (!DuplicateHandle (curr_process,               /* SourceProcessHandle */
-                        old_handle,                 /* SourceHandle */
-                        curr_process,               /* TargetProcessHandle */
-                        (PHANDLE) &new_handle,      /* TargetHandle */
-                        (DWORD) 0,                  /* DesiredAccess */
-                        FALSE,                      /* InheritHandle */
-                        DUPLICATE_SAME_ACCESS))     /* Options */
-    {
-      /* TODO: Translate GetLastError () into errno.  */
-      errno = EMFILE;
-      return -1;
-    }
-
-  nfd = _open_osfhandle ((long) new_handle, mode | O_NOINHERIT);
-  if (nfd < 0)
-    {
-      CloseHandle (new_handle);
-      errno = EMFILE;
-      return -1;
-    }
-
-#  if REPLACE_FCHDIR
-  if (0 <= nfd)
-    result = _gl_register_dup (fd, nfd);
-#  endif
-  return nfd;
-
-#else /* !_WIN32 */
-
-  /* Unix API.  */
-
-# ifdef F_DUPFD_CLOEXEC
-  nfd = fcntl (fd, F_DUPFD_CLOEXEC, 0);
-#  if REPLACE_FCHDIR
-  if (0 <= nfd)
-    nfd = _gl_register_dup (fd, nfd);
-#  endif
-
-# else /* !F_DUPFD_CLOEXEC */
-  nfd = dup (fd);
-  if (0 <= nfd && set_cloexec_flag (nfd, true) < 0)
-    {
-      int saved_errno = errno;
-      close (nfd);
-      nfd = -1;
-      errno = saved_errno;
-    }
-# endif /* !F_DUPFD_CLOEXEC */
-
-  return nfd;
-
-#endif /* !_WIN32 */
+  return fcntl (fd, F_DUPFD_CLOEXEC, 0);
 }