From: Paul Eggert Date: Sat, 25 Jun 2011 08:40:38 +0000 (-0700) Subject: Use gnulib's dup2 module instead of rolling our own. X-Git-Tag: emacs-pretest-24.0.90~104^2~152^2~415 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=7a7ef429182915745380c3074771d9f747dab964;p=emacs.git Use gnulib's dup2 module instead of rolling our own. * Makefile.in (GNULIB_MODULES): Add dup2. * configure.in: Do not check for dup2; gnulib does that now. * lib/dup2.c, m4/dup2.m4: New files, from gnulib. * src/sysdep.c (dup2) [!HAVE_DUP2]: Remove; gnulib now does this. --- diff --git a/ChangeLog b/ChangeLog index 8a908f6b95e..4bf89e35776 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-06-25 Paul Eggert + + Use gnulib's dup2 module instead of rolling our own. + * Makefile.in (GNULIB_MODULES): Add dup2. + * configure.in: Do not check for dup2; gnulib does that now. + * lib/dup2.c, m4/dup2.m4: New files, from gnulib. + 2011-06-23 Paul Eggert * lib/getopt.c, lib/stat.c, m4/gl-comp.m4: Merge from gnulib. diff --git a/Makefile.in b/Makefile.in index 40d76104397..457b5d6472e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -334,6 +334,7 @@ DOS_gnulib_comp.m4 = gl-comp.m4 GNULIB_MODULES = \ alloca-opt \ careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr \ + dup2 \ filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink \ socklen stdarg stdio strftime strtoumax symlink sys_stat GNULIB_TOOL_FLAGS = \ diff --git a/configure.in b/configure.in index fdeae8e6152..0e9f031c164 100644 --- a/configure.in +++ b/configure.in @@ -2645,7 +2645,7 @@ esac AC_SUBST(BLESSMAIL_TARGET) -AC_CHECK_FUNCS(gethostname getdomainname dup2 \ +AC_CHECK_FUNCS(gethostname getdomainname \ rename closedir mkdir rmdir sysinfo getrusage get_current_dir_name \ random lrand48 logb frexp fmod rint cbrt ftime setsid \ strerror fpathconf select euidaccess getpagesize tzset setlocale \ diff --git a/lib/dup2.c b/lib/dup2.c new file mode 100644 index 00000000000..e00dc7b2e3c --- /dev/null +++ b/lib/dup2.c @@ -0,0 +1,132 @@ +/* Duplicate an open file descriptor to a specified file descriptor. + + Copyright (C) 1999, 2004-2007, 2009-2011 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* written by Paul Eggert */ + +#include + +/* Specification. */ +#include + +#include +#include + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Get declarations of the Win32 API functions. */ +# define WIN32_LEAN_AND_MEAN +# include +#endif + +#if HAVE_DUP2 + +# undef dup2 + +int +rpl_dup2 (int fd, int 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; + } + /* 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) + { + 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 (fd, desired_fd); +# ifdef __linux__ + /* Correct a Linux return value. + + */ + if (fd == desired_fd && result == (unsigned int) -EBADF) + { + errno = EBADF; + result = -1; + } +# endif + if (result == 0) + result = desired_fd; + /* Correct a cygwin 1.5.x errno value. */ + else if (result == -1 && errno == EMFILE) + errno = EBADF; +# if REPLACE_FCHDIR + if (fd != desired_fd && result != -1) + result = _gl_register_dup (fd, result); +# endif + return result; +} + +#else /* !HAVE_DUP2 */ + +/* On older platforms, dup2 did not exist. */ + +# ifndef F_DUPFD +static int +dupfd (int fd, int desired_fd) +{ + int duplicated_fd = dup (fd); + if (duplicated_fd < 0 || duplicated_fd == desired_fd) + return duplicated_fd; + else + { + int r = dupfd (fd, desired_fd); + int e = errno; + close (duplicated_fd); + errno = e; + return r; + } +} +# endif + +int +dup2 (int fd, int desired_fd) +{ + int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd; + if (result == -1 || fd == desired_fd) + return result; + close (desired_fd); +# ifdef F_DUPFD + result = fcntl (fd, F_DUPFD, desired_fd); +# if REPLACE_FCHDIR + if (0 <= result) + result = _gl_register_dup (fd, result); +# endif +# else + result = dupfd (fd, desired_fd); +# endif + if (result == -1 && (errno == EMFILE || errno == EINVAL)) + errno = EBADF; + return result; +} +#endif /* !HAVE_DUP2 */ diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 0fd7f520acb..18abe4536fa 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdarg stdio strftime strtoumax symlink sys_stat +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dup2 filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdarg stdio strftime strtoumax symlink sys_stat MOSTLYCLEANFILES += core *.stackdump @@ -159,6 +159,15 @@ EXTRA_libgnu_a_SOURCES += ftoastr.c ## end gnulib module dtoastr +## begin gnulib module dup2 + + +EXTRA_DIST += dup2.c + +EXTRA_libgnu_a_SOURCES += dup2.c + +## end gnulib module dup2 + ## begin gnulib module filemode libgnu_a_SOURCES += filemode.c diff --git a/m4/dup2.m4 b/m4/dup2.m4 new file mode 100644 index 00000000000..8d7f62c8876 --- /dev/null +++ b/m4/dup2.m4 @@ -0,0 +1,76 @@ +#serial 13 +dnl Copyright (C) 2002, 2005, 2007, 2009-2011 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_DUP2], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + m4_ifdef([gl_FUNC_DUP2_OBSOLETE], [ + AC_CHECK_FUNCS_ONCE([dup2]) + if test $ac_cv_func_dup2 = no; then + HAVE_DUP2=0 + AC_LIBOBJ([dup2]) + fi + ], [ + AC_DEFINE([HAVE_DUP2], [1], [Define to 1 if you have the 'dup2' function.]) + ]) + if test $HAVE_DUP2 = 1; then + AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works], + [AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[#include +#include +#include ]], + [int result = 0; +#ifdef FD_CLOEXEC + if (fcntl (1, F_SETFD, FD_CLOEXEC) == -1) + result |= 1; +#endif + if (dup2 (1, 1) == 0) + result |= 2; +#ifdef FD_CLOEXEC + if (fcntl (1, F_GETFD) != FD_CLOEXEC) + result |= 4; +#endif + close (0); + if (dup2 (0, 0) != -1) + result |= 8; + /* Many gnulib modules require POSIX conformance of EBADF. */ + if (dup2 (2, 1000000) == -1 && errno != EBADF) + result |= 16; + return result; + ]) + ], + [gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no], + [case "$host_os" in + mingw*) # on this platform, dup2 always returns 0 for success + gl_cv_func_dup2_works=no;; + cygwin*) # on cygwin 1.5.x, dup2(1,1) returns 0 + gl_cv_func_dup2_works=no;; + linux*) # On linux between 2008-07-27 and 2009-05-11, dup2 of a + # closed fd may yield -EBADF instead of -1 / errno=EBADF. + gl_cv_func_dup2_works=no;; + freebsd*) # on FreeBSD 6.1, dup2(1,1000000) gives EMFILE, not EBADF. + gl_cv_func_dup2_works=no;; + haiku*) # on Haiku alpha 2, dup2(1, 1) resets FD_CLOEXEC. + gl_cv_func_dup2_works=no;; + *) gl_cv_func_dup2_works=yes;; + esac]) + ]) + if test "$gl_cv_func_dup2_works" = no; then + gl_REPLACE_DUP2 + fi + fi +]) + +AC_DEFUN([gl_REPLACE_DUP2], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([dup2]) + if test $ac_cv_func_dup2 = yes; then + REPLACE_DUP2=1 + fi + AC_LIBOBJ([dup2]) +]) diff --git a/m4/gl-comp.m4 b/m4/gl-comp.m4 index 84b3a0962ef..16bb02e686f 100644 --- a/m4/gl-comp.m4 +++ b/m4/gl-comp.m4 @@ -37,6 +37,7 @@ AC_DEFUN([gl_EARLY], # Code from module crypto/sha512: # Code from module dosname: # Code from module dtoastr: + # Code from module dup2: # Code from module extensions: AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) # Code from module filemode: @@ -102,6 +103,8 @@ gl_SHA1 gl_SHA256 gl_SHA512 AC_REQUIRE([gl_C99_STRTOLD]) +gl_FUNC_DUP2 +gl_UNISTD_MODULE_INDICATOR([dup2]) gl_FILEMODE gl_GETLOADAVG if test $HAVE_GETLOADAVG = 0; then @@ -404,6 +407,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/careadlinkat.h lib/dosname.h lib/dtoastr.c + lib/dup2.c lib/filemode.c lib/filemode.h lib/ftoastr.c @@ -453,6 +457,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/00gnulib.m4 m4/alloca.m4 m4/c-strtod.m4 + m4/dup2.m4 m4/extensions.m4 m4/filemode.m4 m4/getloadavg.m4 diff --git a/src/ChangeLog b/src/ChangeLog index b8b3d2a1a9c..792208f7c29 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2011-06-25 Paul Eggert + + Use gnulib's dup2 module instead of rolling our own. + * sysdep.c (dup2) [!HAVE_DUP2]: Remove; gnulib now does this. + 2011-06-24 Juanma Barranquero Move DEFSYM to lisp.h and use everywhere. diff --git a/src/sysdep.c b/src/sysdep.c index 5ad3389dd8f..3a73b1a467b 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2012,37 +2012,6 @@ perror (void) } #endif /* HPUX and not HAVE_PERROR */ -#ifndef HAVE_DUP2 - -/* - * Emulate BSD dup2. First close newd if it already exists. - * Then, attempt to dup oldd. If not successful, call dup2 recursively - * until we are, then close the unsuccessful ones. - */ - -int -dup2 (int oldd, int newd) -{ - register int fd, ret; - - emacs_close (newd); - -#ifdef F_DUPFD - return fcntl (oldd, F_DUPFD, newd); -#else - fd = dup (old); - if (fd == -1) - return -1; - if (fd == new) - return new; - ret = dup2 (old,new); - emacs_close (fd); - return ret; -#endif -} - -#endif /* not HAVE_DUP2 */ - /* * Gettimeofday. Simulate as much as possible. Only accurate * to nearest second. Emacs doesn't use tzp so ignore it for now.