Eric Blake wrote: > > These tests fails the same way on a Debian x86 system (the gcc compile > > farm host "gcc60") as well, see: > > > > http://autobuild.josefsson.org/gnulib/log-200908232214355360000.txt > > That log also shows that test-dup2.c and test-popen.sh are failing; it > appears all of the failures are of the case: close(n),dup2(n,n) not > returning -1 EBADF.
Indeed. This is a Linux bug that affects only 64-bit kernels. It was introduced in July 2008 http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.30.y.git;a=commitdiff;h=6c5d0512a091480c9f981162227fdb1c9d70e555 and only fixed in May 2009 http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.30.y.git;a=commitdiff;h=2b79bc4f7ebbd5af3c8b867968f9f15602d5f802 I'm applying this supposed workaround, but cannot test it because I don't have access to a machine with that version range of Linux kernel and a 64-bit kernel. 2009-08-25 Bruno Haible <br...@clisp.org> 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. *** doc/posix-functions/dup2.texi.orig 2009-08-25 10:51:19.000000000 +0200 --- doc/posix-functions/dup2.texi 2009-08-25 10:51:16.000000000 +0200 *************** *** 17,26 **** mingw. @item ! This function returns 0 for dup2 (1, 1) on some platforms: Cygwin 1.5.x. @item This function is missing on some older platforms. @end itemize --- 17,30 ---- mingw. @item ! 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 *** lib/dup2.c.orig 2009-08-25 10:51:19.000000000 +0200 --- lib/dup2.c 2009-08-25 10:40:31.000000000 +0200 *************** *** 55,60 **** --- 55,70 ---- } # endif result = dup2 (fd, desired_fd); + # ifdef __linux__ + /* Correct a Linux return value. + <http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.30.y.git;a=commitdiff;h=2b79bc4f7ebbd5af3c8b867968f9f15602d5f802> + */ + 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. */ *** m4/dup2.m4.orig 2009-08-25 10:51:19.000000000 +0200 --- m4/dup2.m4 2009-08-25 10:45:48.000000000 +0200 *************** *** 1,4 **** ! #serial 6 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, --- 1,4 ---- ! #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,30 **** AC_LIBOBJ([dup2]) else AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works], ! [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ ! #include <unistd.h> ! ]], [return 1 - dup2 (1, 1);])], [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;; *) gl_cv_func_dup2_works=yes;; ! esac])]) if test "$gl_cv_func_dup2_works" = no; then REPLACE_DUP2=1 AC_LIBOBJ([dup2]) --- 14,41 ---- AC_LIBOBJ([dup2]) else AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works], ! [AC_RUN_IFELSE([ ! AC_LANG_PROGRAM([[#include <unistd.h>]], ! [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]) ! ]) if test "$gl_cv_func_dup2_works" = no; then REPLACE_DUP2=1 AC_LIBOBJ([dup2])