Further testing with tar suggests that fstatat (..., 0)
does not work in general, on AIX 7.1; see
<http://lists.gnu.org/archive/html/bug-tar/2011-09/msg00023.html>.
So, give up entirely on AIX 7.1's fstatat, and fall back on our
replacement fstatat (which is what older AIX releases were using
anyway).
* lib/fstatat.c (fstatat) [HAVE_FSTATAT]: Do not undef. The only
use is now changed to orig_fstatat. This was probably the right
thing to do anyway.
(FSTATAT_AT_FDCWD_0_BROKEN): Remove; no longer used.
(rpl_fstatat) [FSTATAT_ZERO_FLAG_BROKEN]: Remove.
(rpl_fstatat): Simplify, assuming !FSTATAT_ZERO_FLAG_BROKEN.
(AT_FUNC_NAME) [FSTATAT_ZERO_FLAG_BROKEN]: Now rpl_fstatat.
* m4/openat.m4 (gl_FUNC_FSTATAT): Test for the more-general bug
and define FSTATAT_ZERO_FLAG_BROKEN, not FSTATAT_AT_FDCWD_0_BROKEN,
if the bug is found.
(cherry picked from commit
204072b3f5a110d1225d81ca6a929c9f7b76029f)
2011-09-03 Paul Eggert <eggert@cs.ucla.edu>
+ openat: test for fstatat (..., 0) bug
+ Further testing with tar suggests that fstatat (..., 0)
+ does not work in general, on AIX 7.1; see
+ <http://lists.gnu.org/archive/html/bug-tar/2011-09/msg00023.html>.
+ So, give up entirely on AIX 7.1's fstatat, and fall back on our
+ replacement fstatat (which is what older AIX releases were using
+ anyway).
+ * lib/fstatat.c (fstatat) [HAVE_FSTATAT]: Do not undef. The only
+ use is now changed to orig_fstatat. This was probably the right
+ thing to do anyway.
+ (FSTATAT_AT_FDCWD_0_BROKEN): Remove; no longer used.
+ (rpl_fstatat) [FSTATAT_ZERO_FLAG_BROKEN]: Remove.
+ (rpl_fstatat): Simplify, assuming !FSTATAT_ZERO_FLAG_BROKEN.
+ (AT_FUNC_NAME) [FSTATAT_ZERO_FLAG_BROKEN]: Now rpl_fstatat.
+ * m4/openat.m4 (gl_FUNC_FSTATAT): Test for the more-general bug
+ and define FSTATAT_ZERO_FLAG_BROKEN, not FSTATAT_AT_FDCWD_0_BROKEN,
+ if the bug is found.
+
openat: test for fstatat (AT_FDCWD, ..., 0) bug
This tests for another fstatat bug on AIX 7.1:
fstatat (AT_FDCWD, ..., 0) does not work. See
#include <fcntl.h>
#include <string.h>
-#if HAVE_FSTATAT
-
-# undef fstatat
-
-# ifndef FSTATAT_AT_FDCWD_0_BROKEN
-# define FSTATAT_AT_FDCWD_0_BROKEN 0
-# endif
+#if HAVE_FSTATAT && !FSTATAT_ZERO_FLAG_BROKEN
# ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK
# define LSTAT_FOLLOWS_SLASHED_SYMLINK 0
int
rpl_fstatat (int fd, char const *file, struct stat *st, int flag)
{
- int result =
- (FSTATAT_AT_FDCWD_0_BROKEN && fd == AT_FDCWD && flag == 0
- ? stat (file, st)
- : orig_fstatat (fd, file, st, flag));
+ int result = orig_fstatat (fd, file, st, flag);
size_t len;
if (LSTAT_FOLLOWS_SLASHED_SYMLINK || result != 0)
errno = ENOTDIR;
return -1;
}
- result = fstatat (fd, file, st, flag & ~AT_SYMLINK_NOFOLLOW);
+ result = orig_fstatat (fd, file, st, flag & ~AT_SYMLINK_NOFOLLOW);
}
/* Fix stat behavior. */
if (result == 0 && !S_ISDIR (st->st_mode) && file[len - 1] == '/')
return result;
}
-#else /* !HAVE_FSTATAT */
+#else /* !HAVE_FSTATAT || FSTATAT_ZERO_FLAG_BROKEN */
/* On mingw, the gnulib <sys/stat.h> defines `stat' as a function-like
macro; but using it in AT_FUNC_F2 causes compilation failure
then give a diagnostic and exit nonzero.
Otherwise, this function works just like Solaris' fstatat. */
-# define AT_FUNC_NAME fstatat
+# if FSTATAT_ZERO_FLAG_BROKEN
+# define AT_FUNC_NAME rpl_fstatat
+# else
+# define AT_FUNC_NAME fstatat
+# endif
# define AT_FUNC_F1 lstat
# define AT_FUNC_F2 stat_func
# define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW
-# serial 36
+# serial 37
# See if we need to use our replacement for Solaris' openat et al functions.
dnl Copyright (C) 2004-2011 Free Software Foundation, Inc.
else
dnl Test for an AIX 7.1 bug; see
dnl <http://lists.gnu.org/archive/html/bug-tar/2011-09/msg00015.html>.
- AC_CACHE_CHECK([whether fstatat (AT_FDCWD, ..., 0) works],
- [gl_cv_func_fstatat_AT_FDCWD_0],
- [gl_cv_func_fstatat_AT_FDCWD_0=no
- echo xxx >conftest.file
+ AC_CACHE_CHECK([whether fstatat (..., 0) works],
+ [gl_cv_func_fstatat_zero_flag],
+ [gl_cv_func_fstatat_zero_flag=no
AC_RUN_IFELSE(
[AC_LANG_SOURCE(
[[
main (void)
{
struct stat a;
- return fstatat (AT_FDCWD, "conftest.file", &a, 0) != 0;
+ return fstatat (AT_FDCWD, ".", &a, 0) != 0;
}
]])],
- [gl_cv_func_fstatat_AT_FDCWD_0=yes])])
+ [gl_cv_func_fstatat_zero_flag=yes])])
- case $gl_cv_func_fstatat_AT_FDCWD_0+$gl_cv_func_lstat_dereferences_slashed_symlink in
+ case $gl_cv_func_fstatat_zero_flag+$gl_cv_func_lstat_dereferences_slashed_symlink in
yes+yes) ;;
*) REPLACE_FSTATAT=1
- if test $gl_cv_func_fstatat_AT_FDCWD_0 != yes; then
- AC_DEFINE([FSTATAT_AT_FDCWD_0_BROKEN], [1],
- [Define to 1 if fstatat (AT_FDCWD, ..., 0) does not work,
+ if test $gl_cv_func_fstatat_zero_flag != yes; then
+ AC_DEFINE([FSTATAT_ZERO_FLAG_BROKEN], [1],
+ [Define to 1 if fstatat (..., 0) does not work,
as in AIX 7.1.])
fi
;;