From: Bruno Haible Date: Tue, 25 Aug 2009 08:52:51 +0000 (+0200) Subject: dup2: work around a Linux bug. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eeee74f5efe5e3c9f8f1198478b719921f29242c;p=pspp dup2: work around a Linux bug. --- diff --git a/ChangeLog b/ChangeLog index cd6a1e6da0..952e5c86d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-08-25 Bruno Haible + + dup2: work around a Linux bug. + * m4/dup2.m4 (gl_FUNC_DUP2): Test for the Linux bug. + * lib/dup2.c (rpl_dup2): Correct the return value if it is -EBADF. + * doc/posix-functions/dup2.texi: Mention the Linux bug. + Reported by Simon Josefsson. + 2009-08-25 Jim Meyering libguestfs uses gnulib diff --git a/doc/posix-functions/dup2.texi b/doc/posix-functions/dup2.texi index c8f2ca180d..6509f0e286 100644 --- a/doc/posix-functions/dup2.texi +++ b/doc/posix-functions/dup2.texi @@ -17,9 +17,13 @@ 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: +This function returns 0 for @code(dup2 (1, 1)} on some platforms: Cygwin 1.5.x. +@item +This function may return @code{-EBADF} instead of @code{-1} on some platforms: +Linux releases between July 2008 and May 2009. + @item This function is missing on some older platforms. @end itemize diff --git a/lib/dup2.c b/lib/dup2.c index 6b6f45db4d..fb3ffb0df0 100644 --- a/lib/dup2.c +++ b/lib/dup2.c @@ -55,6 +55,16 @@ rpl_dup2 (int fd, int desired_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. */ diff --git a/m4/dup2.m4 b/m4/dup2.m4 index 2abc74cdc5..2e846c0c7f 100644 --- a/m4/dup2.m4 +++ b/m4/dup2.m4 @@ -1,4 +1,4 @@ -#serial 6 +#serial 7 dnl Copyright (C) 2002, 2005, 2007, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -14,17 +14,28 @@ AC_DEFUN([gl_FUNC_DUP2], AC_LIBOBJ([dup2]) else AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ -#include -]], [return 1 - dup2 (1, 1);])], + [AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[#include ]], + [if (dup2 (1, 1) == 0) + return 1; + close (0); + if (dup2 (0, 0) != -1) + return 1; + return 0; + ]) + ], [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;; *) gl_cv_func_dup2_works=yes;; - esac])]) + esac]) + ]) if test "$gl_cv_func_dup2_works" = no; then REPLACE_DUP2=1 AC_LIBOBJ([dup2])