openat: work around AIX 7.1 fstatat issue
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 1 Sep 2011 19:53:10 +0000 (12:53 -0700)
committerIan Beckwith <ianb@erislabs.net>
Wed, 7 Sep 2011 23:52:43 +0000 (00:52 +0100)
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.
(cherry picked from commit de1fa2ac9aeb9f70a042ee3faa2b7712e65a278b)

ChangeLog
lib/fstatat.c
m4/openat.m4

index cfab565..0a2351e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2011-09-01  Paul Eggert  <eggert@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  <bruno@clisp.org>
 
        sys_select: Avoid a syntax error regarding timespec_t on IRIX 6.5.
index b217126..d592d60 100644 (file)
 
 /* 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 */
index aa6838d..5683650 100644 (file)
@@ -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
 ])