1
/* Duplicate an open file descriptor to a specified file descriptor.
3
Copyright (C) 1999, 2004-2007, 2009-2011 Free Software Foundation, Inc.
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 3 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
/* written by Paul Eggert */
28
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
29
/* Get declarations of the Win32 API functions. */
30
# define WIN32_LEAN_AND_MEAN
39
rpl_dup2 (int fd, int desired_fd)
42
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
43
/* If fd is closed, mingw hangs on dup2 (fd, fd). If fd is open,
44
dup2 (fd, fd) returns 0, but all further attempts to use fd in
45
future dup2 calls will hang. */
48
if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE)
55
/* Wine 1.0.1 return 0 when desired_fd is negative but not -1:
56
http://bugs.winehq.org/show_bug.cgi?id=21289 */
62
# elif !defined __linux__
63
/* On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC. */
65
return fcntl (fd, F_GETFL) == -1 ? -1 : fd;
67
result = dup2 (fd, desired_fd);
69
/* Correct a Linux return value.
70
<http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.30.y.git;a=commitdiff;h=2b79bc4f7ebbd5af3c8b867968f9f15602d5f802>
72
if (fd == desired_fd && result == (unsigned int) -EBADF)
80
/* Correct a cygwin 1.5.x errno value. */
81
else if (result == -1 && errno == EMFILE)
84
if (fd != desired_fd && result != -1)
85
result = _gl_register_dup (fd, result);
90
#else /* !HAVE_DUP2 */
92
/* On older platforms, dup2 did not exist. */
96
dupfd (int fd, int desired_fd)
98
int duplicated_fd = dup (fd);
99
if (duplicated_fd < 0 || duplicated_fd == desired_fd)
100
return duplicated_fd;
103
int r = dupfd (fd, desired_fd);
105
close (duplicated_fd);
113
dup2 (int fd, int desired_fd)
115
int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd;
116
if (result == -1 || fd == desired_fd)
120
result = fcntl (fd, F_DUPFD, desired_fd);
123
result = _gl_register_dup (fd, result);
126
result = dupfd (fd, desired_fd);
128
if (result == -1 && (errno == EMFILE || errno == EINVAL))
132
#endif /* !HAVE_DUP2 */