OK, thanks, I think I see the problem now: on AIX 7.1, fstatat is a macro and has the same problems as lstat, fstat, and stat. This means fstatat.c can't simply "#define fstatat rpl_fstatat" but must do something trickier. I have started this by applying the following patches to gnulib and will follow up by sending a tar-specific patch to you in a different email.
>From de1fa2ac9aeb9f70a042ee3faa2b7712e65a278b Mon Sep 17 00:00:00 2001 From: Paul Eggert <egg...@cs.ucla.edu> Date: Thu, 1 Sep 2011 12:53:10 -0700 Subject: [PATCH 1/2] openat: work around AIX 7.1 fstatat issue This should fix the problem that was not properly fixed in the previous change, dated 2011-08-30. * lib/fstatat.c: Include <sys/stat.h> twice, the first with __need_system_stat_h defined. (orig_fstatat) [HAVE_FSTATAT]: New function. (rpl_fstatat): Go back to the old way of doing things, except call orig_fstatat instead of fstatat. * m4/openat.m4 (gl_FUNC_FSTATAT): Remove unnecessary check for openat. Remove unnecessary check whether fstatat fills in st_size etc. --- ChangeLog | 13 +++++++++++++ lib/fstatat.c | 29 ++++++++++++++++++++--------- m4/openat.m4 | 51 ++++----------------------------------------------- 3 files changed, 37 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index bee4d57..548e39d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-09-01 Paul Eggert <egg...@cs.ucla.edu> + + openat: work around AIX 7.1 fstatat issue + This should fix the problem that was not properly fixed + in the previous change, dated 2011-08-30. + * lib/fstatat.c: Include <sys/stat.h> twice, the first with + __need_system_stat_h defined. + (orig_fstatat) [HAVE_FSTATAT]: New function. + (rpl_fstatat): Go back to the old way of doing things, + except call orig_fstatat instead of fstatat. + * m4/openat.m4 (gl_FUNC_FSTATAT): Remove unnecessary check for openat. + Remove unnecessary check whether fstatat fills in st_size etc. + 2011-09-01 Bruno Haible <br...@clisp.org> sys_select: Avoid a syntax error regarding timespec_t on IRIX 6.5. diff --git a/lib/fstatat.c b/lib/fstatat.c index b217126..d592d60 100644 --- a/lib/fstatat.c +++ b/lib/fstatat.c @@ -17,15 +17,31 @@ /* Written by Paul Eggert and Jim Meyering. */ +/* If the user's config.h happens to include <sys/stat.h>, let it include only + the system's <sys/stat.h> here, so that orig_fstatat doesn't recurse to + rpl_fstatat. */ +#define __need_system_sys_stat_h #include <config.h> +/* Get the original definition of fstatat. It might be defined as a macro. */ +#include <sys/stat.h> +#undef __need_system_sys_stat_h + +#if HAVE_FSTATAT +static inline int +orig_fstatat (int fd, char const *filename, struct stat *buf, int flags) +{ + return fstatat (fd, filename, buf, flags); +} +#endif + #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #include <string.h> -#if HAVE_FSTATAT && ! FSTATAT_ST_SIZE_ETC_BROKEN +#if HAVE_FSTATAT # undef fstatat @@ -38,7 +54,7 @@ int rpl_fstatat (int fd, char const *file, struct stat *st, int flag) { - int result = fstatat (fd, file, st, flag); + int result = orig_fstatat (fd, file, st, flag); size_t len; if (result != 0) @@ -65,12 +81,7 @@ rpl_fstatat (int fd, char const *file, struct stat *st, int flag) return result; } -#else /* ! (HAVE_FSTATAT && ! FSTATAT_ST_SIZE_ETC_BROKEN) */ - -# if HAVE_FSTATAT -# undef fstatat -# define fstatat rpl_fstatat -# endif +#else /* !HAVE_FSTATAT */ /* On mingw, the gnulib <sys/stat.h> defines `stat' as a function-like macro; but using it in AT_FUNC_F2 causes compilation failure @@ -112,4 +123,4 @@ stat_func (char const *name, struct stat *st) # undef AT_FUNC_POST_FILE_PARAM_DECLS # undef AT_FUNC_POST_FILE_ARGS -#endif /* ! (HAVE_FSTATAT && ! FSTATAT_ST_SIZE_ETC_BROKEN) */ +#endif /* !HAVE_FSTATAT */ diff --git a/m4/openat.m4 b/m4/openat.m4 index aa6838d..5683650 100644 --- a/m4/openat.m4 +++ b/m4/openat.m4 @@ -1,4 +1,4 @@ -# serial 34 +# serial 35 # See if we need to use our replacement for Solaris' openat et al functions. dnl Copyright (C) 2004-2011 Free Software Foundation, Inc. @@ -160,55 +160,12 @@ AC_DEFUN([gl_FUNC_FSTATAT], AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK]) - AC_CHECK_FUNCS_ONCE([fstatat openat]) + AC_CHECK_FUNCS_ONCE([fstatat]) if test $ac_cv_func_fstatat = no; then HAVE_FSTATAT=0 - else - AC_CACHE_CHECK([whether fstatat fills in st_size etc.], - [gl_cv_func_fstatat_st_size_etc], - [gl_cv_func_fstatat_st_size_etc=no - echo xxx >conftest.file - AC_RUN_IFELSE( - [AC_LANG_SOURCE( - [[ - #include <fcntl.h> - #include <sys/stat.h> - - int - main (void) - { - struct stat a; - struct stat b; - if (fstatat (AT_FDCWD, "conftest.file", &a, - AT_SYMLINK_NOFOLLOW) - != 0) - return 1; - if (lstat ("conftest.file", &b) != 0) - return 2; - if (a.st_size != b.st_size) return 3; - if (a.st_dev != b.st_dev) return 4; - if (a.st_ino != b.st_ino) return 5; - if (a.st_mode != b.st_mode) return 6; - if (a.st_nlink != b.st_nlink) return 7; - if (a.st_uid != b.st_uid) return 8; - if (a.st_gid != b.st_gid) return 9; - /* Don't check time members, to avoid caching issues. */ - return 0; - } - ]])], - [gl_cv_func_fstatat_st_size_etc=yes])]) - - case $gl_cv_func_fstatat_st_size_etc+$gl_cv_func_lstat_dereferences_slashed_symlink in - yes+yes) ;; - *) REPLACE_FSTATAT=1 - if test $gl_cv_func_fstatat_st_size_etc != yes; then - AC_DEFINE([FSTATAT_ST_SIZE_ETC_BROKEN], [1], - [Define to 1 if fstatat does not fill in st_size etc., - as in AIX 7.1.]) - fi - ;; - esac + elif test $gl_cv_func_lstat_dereferences_slashed_symlink != yes; then + REPLACE_FSTATAT=1 fi ]) -- 1.7.4.4 >From 6cf1a9531a2d12c913b14c1caf1d986c5cf034a2 Mon Sep 17 00:00:00 2001 From: Paul Eggert <egg...@cs.ucla.edu> Date: Thu, 1 Sep 2011 13:10:42 -0700 Subject: [PATCH 2/2] * lib/fstatat.c: Include <sys/types.h> before <sys/stat.h>. --- lib/fstatat.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/lib/fstatat.c b/lib/fstatat.c index d592d60..a904e43 100644 --- a/lib/fstatat.c +++ b/lib/fstatat.c @@ -24,6 +24,7 @@ #include <config.h> /* Get the original definition of fstatat. It might be defined as a macro. */ +#include <sys/types.h> #include <sys/stat.h> #undef __need_system_sys_stat_h -- 1.7.4.4