Mercurial > hg > octave-lyh > gnulib-hg
changeset 11729:96bc5f7886d1
dup2: fix more mingw problems
* lib/dup2.c (rpl_dup2) [_WIN32]: Avoid hanging when duplicating
fd to itself.
* doc/posix-functions/dup2.texi (dup2): Document the bug.
* lib/unistd.in.h (dup2) [REPLACE_FCHDIR]: Avoid name collision.
* lib/fchdir.c (dup2): Manage preprocessor macros correctly.
(rpl_dup2_fchdir): Rename from rpl_dup2, and let dup2 module take
care of mingw bugs.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Tue, 21 Jul 2009 09:00:57 -0600 |
parents | 91887b0a2a0f |
children | 1bd4d344ee8d |
files | ChangeLog doc/posix-functions/dup2.texi lib/dup2.c lib/fchdir.c lib/unistd.in.h |
diffstat | 5 files changed, 56 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-07-21 Eric Blake <ebb9@byu.net> + + dup2: fix more mingw problems + * lib/dup2.c (rpl_dup2) [_WIN32]: Avoid hanging when duplicating + fd to itself. + * doc/posix-functions/dup2.texi (dup2): Document the bug. + * lib/unistd.in.h (dup2) [REPLACE_FCHDIR]: Avoid name collision. + * lib/fchdir.c (dup2): Manage preprocessor macros correctly. + (rpl_dup2_fchdir): Rename from rpl_dup2, and let dup2 module take + care of mingw bugs. + 2009-07-21 Jim Meyering <meyering@redhat.com> vc-list-files: avoid failure when /bin/sh is dash
--- a/doc/posix-functions/dup2.texi +++ b/doc/posix-functions/dup2.texi @@ -13,6 +13,10 @@ mingw. @item +This function can hang when duplicating an fd to itself on some platforms: +mingw. + +@item This function returns 0 for dup2 (1, 1) on some platforms: Cygwin 1.5.x.
--- a/lib/dup2.c +++ b/lib/dup2.c @@ -26,19 +26,42 @@ #include <errno.h> #include <fcntl.h> +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Get declarations of the Win32 API functions. */ +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +#endif + #if REPLACE_DUP2 -/* On mingw, dup2 exists, but always returns 0 for success. */ + +# undef dup2 + int -dup2 (int fd, int desired_fd) -#undef dup2 +rpl_dup2 (int fd, int desired_fd) { - int result = dup2 (fd, desired_fd); + int result; +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* If fd is closed, mingw hangs on dup2 (fd, fd). If fd is open, + dup2 (fd, fd) returns 0, but all further attempts to use fd in + future dup2 calls will hang. */ + if (fd == desired_fd) + { + if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + return fd; + } +# endif + result = dup2 (fd, desired_fd); if (result == 0) result = desired_fd; return result; } #else /* !REPLACE_DUP2 */ + /* On older platforms, dup2 did not exist. */ # ifndef F_DUPFD
--- a/lib/fchdir.c +++ b/lib/fchdir.c @@ -172,18 +172,19 @@ return newfd; } +/* Our <unistd.h> replacement overrides dup2 twice; be sure to pick + the one we want. */ +#if REPLACE_DUP2 +# undef dup2 +# define dup2 rpl_dup2 +#endif + int -rpl_dup2 (int oldfd, int newfd) -#undef dup2 +rpl_dup2_fchdir (int oldfd, int newfd) { int retval = dup2 (oldfd, newfd); -#if REPLACE_DUP2 - /* Inline mingw replacement from dup2.c. */ - if (retval == 0) - retval = newfd; -#endif - if (retval >= 0 && oldfd >= 0 && newfd >= 0 && newfd != oldfd) + if (retval >= 0 && newfd != oldfd) { ensure_dirs_slot (newfd); if (newfd < dirs_allocated)
--- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -217,10 +217,12 @@ # define dup rpl_dup extern int dup (int); -# if !@REPLACE_DUP2@ -# define dup2 rpl_dup2 + +# if @REPLACE_DUP2@ +# undef dup2 +# endif +# define dup2 rpl_dup2_fchdir extern int dup2 (int, int); -# endif # endif #elif defined GNULIB_POSIXCHECK