Gary V. Vaughan wrote: >> ix86 SLED 10 gcc 4.1.2 (fchownat, rename, renameat)
I'm seeing this failure on a Linux/x86 machine (SUSE Linux Enterprise Server 10, Linux 2.6.16.60, glibc 2.4): test-chown.h:79: assertion failed FAIL: test-fchownat The call that fails is ASSERT (func ("", -1, -1) == -1); in other words ASSERT (fchownat (3, "", -1, -1, 0) == -1); The test is right, because POSIX:2008 says about chown, fchownat: "These functions shall fail if: [ENOENT] A component of path does not name an existing file or path is an empty string." The function fchownat, on this platform, comes from glibc: $ nm test-fchownat|grep chown 0804c320 t do_chown 0804c2e0 t do_lchown U fchownat@@GLIBC_2.4 0804b370 t test_chown 08048e10 t test_lchown and strace shows this system call: chown32("/proc/self/fd/3/", -1, -1) = 0 So the bug is in glibc. It was fixed there on 2009-10-30, following the report at <http://sources.redhat.com/bugzilla/show_bug.cgi?id=10609>. This fixes it for me. Jim, is this OK to push? 2010-11-12 Bruno Haible <br...@clisp.org> openat: Work around glibc bug with fchownat() and empty file names. * m4/openat.m4 (gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG): New macro. (gl_FUNC_FCHOWNAT): Invoke it. * lib/fchownat.c (rpl_fchownat): Handle the empty file name specially. * doc/posix-functions/fchownat.texi: Document the glibc bug. Reported by Gary V. Vaughan <g...@gnu.org>. --- doc/posix-functions/fchownat.texi.orig Sat Nov 13 13:49:35 2010 +++ doc/posix-functions/fchownat.texi Sat Nov 13 04:06:29 2010 @@ -17,6 +17,9 @@ @code{AT_SYMLINK_NOFOLLOW}: Linux kernel 2.6.17. @item +This function does not fail for an empty filename on some platforms: +Linux with glibc < 2.11. +...@item This function is missing on some platforms: glibc 2.3.6, MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Cygwin 1.5.x, mingw, Interix 3.5, BeOS. --- lib/fchownat.c.orig Sat Nov 13 13:49:35 2010 +++ lib/fchownat.c Sat Nov 13 03:24:19 2010 @@ -88,6 +88,13 @@ if (flag == AT_SYMLINK_NOFOLLOW) return local_lchownat (fd, file, owner, group); # endif +# if FCHOWNAT_EMPTY_FILENAME_BUG + if (file[0] == '\0') + { + errno = ENOENT; + return -1; + } +# endif # if CHOWN_TRAILING_SLASH_BUG { size_t len = strlen (file); --- m4/openat.m4.orig Sat Nov 13 13:49:35 2010 +++ m4/openat.m4 Sat Nov 13 04:27:16 2010 @@ -1,4 +1,4 @@ -# serial 30 +# serial 31 # See if we need to use our replacement for Solaris' openat et al functions. dnl Copyright (C) 2004-2010 Free Software Foundation, Inc. @@ -96,6 +99,38 @@ AS_IF([test $gl_cv_func_fchownat_nofollow_works = no], [$1], [$2]) ]) +# gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG([ACTION-IF-BUGGY[, ACTION-IF-NOT_BUGGY]]) +AC_DEFUN([gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG], +[ + dnl Persuade glibc <unistd.h> to declare fchownat(). + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CACHE_CHECK([whether fchownat works with an empty file name], + [gl_cv_func_fchownat_empty_filename_works], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include <unistd.h> + #include <fcntl.h> + ]], + [[int fd; + int ret; + if (mkdir ("conftestdir", 0700) < 0) + return 2; + fd = open ("conftestdir", O_RDONLY); + if (fd < 0) + return 3; + ret = fchownat (fd, "", -1, -1, 0); + close (fd); + rmdir ("conftestdir"); + return ret == 0; + ]])], + [gl_cv_func_fchownat_empty_filename_works=yes], + [gl_cv_func_fchownat_empty_filename_works=no], + [gl_cv_func_fchownat_empty_filename_works="guessing no"]) + ]) + AS_IF([test "$gl_cv_func_fchownat_empty_filename_works" != yes], [$1], [$2]) +]) + # If we have the fchownat function, and it has the bug (in glibc-2.4) # that it dereferences symlinks even with AT_SYMLINK_NOFOLLOW, then # use the replacement function. @@ -112,6 +148,12 @@ [Define to 1 if your platform has fchownat, but it cannot perform lchown tasks.]) ]) + gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG( + [REPLACE_FCHOWNAT=1 + AC_DEFINE([FCHOWNAT_EMPTY_FILENAME_BUG], [1], + [Define to 1 if your platform has fchownat, but it does + not reject an empty file name.]) + ]) if test $REPLACE_CHOWN = 1; then REPLACE_FCHOWNAT=1 fi],