# HG changeset patch # User Paul Eggert # Date 1316840660 25200 # Node ID 1090350f29b0636b2c332d11399e2bea8d98d986 # Parent f19a42ecd35b07198a10c9c376285d4bb3456f30 dup2: clarify by coalescing Windows-specific material * lib/dup2.c: Move '#include "msvc-inval.h"' and '#include "msvc-nothrow.h"' to the Windows-specific section, so that the Emacs source need not contain these include files. (ms_windows_dup2): Rename from dup2_nothrow, and move all the Windows-specific fixes into this function rather than just the nothrow fix, as this shortens and clarifies the code. Always define as a function, as that's a bit cleaner than having it be sometimes a function and sometimes a macro. (rpl_dup2): Move the Windows-specific stuff out of here and into ms_windows_dup2. Don't protect the Haiku-related fix with "#if !defined __linux__", as the same code also works around a Linux kernel bug, and it doesn't add any system calls on any platform. Add comment about FreeBSD 6.1. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2011-09-23 Paul Eggert + dup2: clarify by coalescing Windows-specific material + * lib/dup2.c: Move '#include "msvc-inval.h"' and '#include + "msvc-nothrow.h"' to the Windows-specific section, so that the + Emacs source need not contain these include files. + (ms_windows_dup2): Rename from dup2_nothrow, and move all the + Windows-specific fixes into this function rather than just the + nothrow fix, as this shortens and clarifies the code. Always + define as a function, as that's a bit cleaner than having it be + sometimes a function and sometimes a macro. + (rpl_dup2): Move the Windows-specific stuff out of here and into + ms_windows_dup2. Don't protect the Haiku-related fix with + "#if !defined __linux__", as the same code also works around + a Linux kernel bug, and it doesn't add any system calls on any + platform. Add comment about FreeBSD 6.1. + sigprocmask: move #include directive * lib/sigprocmask.c: Move '#include "msvc-inval.h"' to the Windows-specific section, so that the Emacs source need not diff --git a/lib/dup2.c b/lib/dup2.c --- a/lib/dup2.c +++ b/lib/dup2.c @@ -25,48 +25,24 @@ #include #include -#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ -/* Get declarations of the Win32 API functions. */ -# define WIN32_LEAN_AND_MEAN -# include -/* Get _get_osfhandle. */ -# include "msvc-nothrow.h" -#endif - -#include "msvc-inval.h" - #if HAVE_DUP2 # undef dup2 -# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# if defined _WIN32 || defined __WIN32__ +# include "msvc-inval.h" +# ifndef __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include +# include "msvc-nothrow.h" +# endif + static inline int -dup2_nothrow (int fd, int desired_fd) +ms_windows_dup2 (int fd, int desired_fd) { int result; - TRY_MSVC_INVAL - { - result = dup2 (fd, desired_fd); - } - CATCH_MSVC_INVAL - { - result = -1; - errno = EBADF; - } - DONE_MSVC_INVAL; - - return result; -} -# else -# define dup2_nothrow dup2 -# endif - -int -rpl_dup2 (int fd, int desired_fd) -{ - int result; -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# ifndef __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. */ @@ -79,6 +55,8 @@ } return fd; } +# endif + /* Wine 1.0.1 return 0 when desired_fd is negative but not -1: http://bugs.winehq.org/show_bug.cgi?id=21289 */ if (desired_fd < 0) @@ -86,28 +64,41 @@ errno = EBADF; return -1; } -# elif !defined __linux__ - /* On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC. */ - if (fd == desired_fd) - return fcntl (fd, F_GETFL) == -1 ? -1 : fd; -# endif - result = dup2_nothrow (fd, desired_fd); - -# ifdef __linux__ - /* Correct a Linux return value. - - */ - if (fd == desired_fd && result == (unsigned int) -EBADF) + TRY_MSVC_INVAL + { + result = dup2 (fd, desired_fd); + } + CATCH_MSVC_INVAL { errno = EBADF; result = -1; } -# endif + DONE_MSVC_INVAL; + + /* Cygwin 1.5.x dup2 (1, 1) returns 0. */ if (result == 0) result = desired_fd; - /* Correct a cygwin 1.5.x errno value. */ - else if (result == -1 && errno == EMFILE) + + return result; +} +# define dup2 ms_windows_dup2 +# endif + +int +rpl_dup2 (int fd, int desired_fd) +{ + int result; + + /* On Linux kernels 2.6.26-2.6.29, dup2 (fd, fd) returns -EBADF. + On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC. */ + if (fd == desired_fd) + return fcntl (fd, F_GETFL) == -1 ? -1 : fd; + + result = dup2 (fd, desired_fd); + + /* Correct an errno value on FreeBSD 6.1 and Cygwin 1.5.x. */ + if (result == -1 && errno == EMFILE) errno = EBADF; # if REPLACE_FCHDIR if (fd != desired_fd && result != -1)