- 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;
-
- if (old_handle == INVALID_HANDLE_VALUE)
- {
- /* 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;
- }
-
- 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, O_BINARY | 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 */