bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

improve stat on mingw, Solaris


From: Eric Blake
Subject: improve stat on mingw, Solaris
Date: Wed, 16 Sep 2009 21:59:18 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

As promised, here's another patch series I'm working on.  I need to test it 
further before committing, especially to see if fstatat on Solaris 9 needs the 
same help (I have easy access to Solaris 8 and 10, but not to Solaris 9; 
Solaris 8 lacks *at functions, and Solaris 10 fixed many (but not all) trailing 
slash bugs; but given that Solaris 9 has fstatat and buggy lstat, the fstatat 
replacement probably needs to do trailing slash correction for stat as well as 
lstat).

I don't know of any easy way to #define stat rpl_stat without breaking struct 
stat, so I went with an object-like macro instead.  But that has its own 
drawbacks (such as not working in the macro usage of at-func.c, or where using 
&stat to get a function pointer won't grab the replacement).  Does anyone have 
any better ideas?


From: Eric Blake <address@hidden>
Date: Tue, 15 Sep 2009 07:11:40 -0600
Subject: [PATCH 1/3] stat: new module, for mingw bug

* modules/stat: New file.
* lib/stat.c: Likewise.
* m4/stat.m4 (gl_FUNC_STAT): Likewise.
* m4/sys_stat_h.m4 (gl_SYS_STAT_H_DEFAULTS): Add witnesses.
* modules/sys_stat (Makefile.am): Use them.
* lib/sys_stat.in.h (stat): Declare replacement.
* lib/openat.c (fstatat): Deal with lstat and stat being function
macros.
* modules/openat (Depends-on): Add inline.
* MODULES.html.sh (systems lacking POSIX:2008): Mention module.
* doc/posix-functions/stat.texi (stat): Likewise.
* modules/stat-tests: New test.
* tests/test-stat.c: Likewise.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog                     |   17 +++++++++
 MODULES.html.sh               |    1 +
 doc/posix-functions/stat.texi |   14 +++++++-
 lib/openat.c                  |   20 ++++++++++-
 lib/stat.c                    |   78 ++++++++++++++++++++++++++++++++++++++++
 lib/sys_stat.in.h             |   16 ++++++++
 m4/stat.m4                    |   31 ++++++++++++++++
 m4/sys_stat_h.m4              |    4 ++-
 modules/openat                |    1 +
 modules/stat                  |   26 +++++++++++++
 modules/stat-tests            |   12 ++++++
 modules/sys_stat              |    2 +
 tests/test-stat.c             |   79 +++++++++++++++++++++++++++++++++++++++++
 13 files changed, 298 insertions(+), 3 deletions(-)
 create mode 100644 lib/stat.c
 create mode 100644 m4/stat.m4
 create mode 100644 modules/stat
 create mode 100644 modules/stat-tests
 create mode 100644 tests/test-stat.c

diff --git a/ChangeLog b/ChangeLog
index 5a76332..c339f25 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2009-09-16  Eric Blake  <address@hidden>

+       stat: new module, for mingw bug
+       * modules/stat: New file.
+       * lib/stat.c: Likewise.
+       * m4/stat.m4 (gl_FUNC_STAT): Likewise.
+       * m4/sys_stat_h.m4 (gl_SYS_STAT_H_DEFAULTS): Add witnesses.
+       * modules/sys_stat (Makefile.am): Use them.
+       * lib/sys_stat.in.h (stat): Declare replacement.
+       * lib/openat.c (fstatat): Deal with lstat and stat being function
+       macros.
+       * modules/openat (Depends-on): Add inline.
+       * MODULES.html.sh (systems lacking POSIX:2008): Mention module.
+       * doc/posix-functions/stat.texi (stat): Likewise.
+       * modules/stat-tests: New test.
+       * tests/test-stat.c: Likewise.
+
+2009-09-16  Eric Blake  <address@hidden>
+
        canonicalize: in CAN_ALL_BUT_LAST, allow trailing slash
        * lib/canonicalize.c (canonicalize_filename_mode): Skip trailing
        slashes when checking if last component is missing.
diff --git a/MODULES.html.sh b/MODULES.html.sh
index 76741b3..fbea183 100755
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -2331,6 +2331,7 @@ func_all_modules ()
   func_module socket
   func_module spawn
   func_module sprintf-posix
+  func_module stat
   func_module strdup-posix
   func_module string
   func_module strings
diff --git a/doc/posix-functions/stat.texi b/doc/posix-functions/stat.texi
index 97992e4..3160cc7 100644
--- a/doc/posix-functions/stat.texi
+++ b/doc/posix-functions/stat.texi
@@ -4,10 +4,14 @@ stat

 POSIX specification: @url
{http://www.opengroup.org/onlinepubs/9699919799/functions/stat.html}

-Gnulib module: ---
+Gnulib module: stat

 Portability problems fixed by Gnulib:
 @itemize
address@hidden
+On some platforms, @code{stat(".",buf)} and @code{stat("./",buf)} give
+different results:
+mingw.
 @end itemize

 Portability problems not fixed by Gnulib:
@@ -19,4 +23,12 @@ stat
 @item
 Cygwin's @code{stat} function sometimes sets @code{errno} to @code{EACCES} when
 @code{ENOENT} would be more appropriate.
address@hidden
+On Windows platforms (excluding Cygwin), @code{d_ino} is always 0.
address@hidden
+Because of the definition of @code{struct stat}, it is not possible to
+portably replace @code{stat} via an object-like macro.  Therefore,
+expressions such as @code{(islnk ? lstat : stat) (name, buf)} are not
+portable, and should instead be written @code{islnk ? lstat (name,
+buf) : stat (name, buf)}.
 @end itemize
diff --git a/lib/openat.c b/lib/openat.c
index e1471b8..e9771d4 100644
--- a/lib/openat.c
+++ b/lib/openat.c
@@ -158,6 +158,24 @@ openat_needs_fchdir (void)
   return needs_fchdir;
 }

+/* On mingw, the gnulib <sys/stat.h> defines `stat' as a function-like
+   macro; but using it in AT_FUNC_F2 causes compilation failure
+   because the preprocessor sees a use of a macro that requires two
+   arguments but is only given one.  Hence, we need an inline
+   forwarder to get past the preprocessor.  */
+static inline int
+stat_func (char const *name, struct stat *st)
+{
+  return stat (name, st);
+}
+
+/* Likewise, if there is no native `lstat', then the gnulib
+   <sys/stat.h> defined it as stat, which also needs adjustment.  */
+#if !HAVE_LSTAT
+# undef lstat
+# define lstat stat_func
+#endif
+
 /* Replacement for Solaris' function by the same name.
    <http://www.google.com/search?q=fstatat+site:docs.sun.com>
    First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE").
@@ -168,7 +186,7 @@ openat_needs_fchdir (void)

 #define AT_FUNC_NAME fstatat
 #define AT_FUNC_F1 lstat
-#define AT_FUNC_F2 stat
+#define AT_FUNC_F2 stat_func
 #define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW
 #define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag
 #define AT_FUNC_POST_FILE_ARGS        , st
diff --git a/lib/stat.c b/lib/stat.c
new file mode 100644
index 0000000..07aa323
--- /dev/null
+++ b/lib/stat.c
@@ -0,0 +1,78 @@
+/* Work around some limitations of mingw stat.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* written by Eric Blake */
+
+#include <config.h>
+
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <string.h>
+
+#undef stat
+
+/* For now, mingw is the only known platform where stat(".") and
+   stat("./") give different results.  Mingw stat has other bugs (such
+   as st_ino always being 0 on success) which this wrapper does not
+   work around.  But at least this implementation provides the ability
+   to emulate fchdir correctly.  */
+
+int
+rpl_stat (char const *name, struct stat *st)
+{
+  int result = stat (name, st);
+  if (result == -1 && errno == ENOENT)
+    {
+      /* Due to mingw's oddities, there are some directories (like
+         c:\) where stat() only succeeds with a trailing slash, and
+         other directories (like c:\windows) where stat() only
+         succeeds without a trailing slash.  But we want the two to be
+         synonymous, since chdir() manages either style.  Likewise, Mingw also
+         reports ENOENT for names longer than PATH_MAX, when we want
+         ENAMETOOLONG, and for stat("file/"), when we want ENOTDIR.
+         Fortunately, mingw PATH_MAX is small enough for stack
+         allocation.  */
+      char fixed_name[PATH_MAX + 1] = {0};
+      size_t len = strlen (name);
+      bool check_dir = false;
+      if (PATH_MAX <= len)
+        errno = ENAMETOOLONG;
+      else if (len)
+        {
+          strcpy (fixed_name, name);
+          if (ISSLASH (fixed_name[len - 1]))
+            {
+              check_dir = true;
+              while (len && ISSLASH (fixed_name[len - 1]))
+                fixed_name[--len] = '\0';
+              if (!len)
+                fixed_name[0] = '/';
+            }
+          else
+            fixed_name[len++] = '/';
+          result = stat (fixed_name, st);
+          if (result == 0 && check_dir && !S_ISDIR (st->st_mode))
+            {
+              result = -1;
+              errno = ENOTDIR;
+            }
+        }
+    }
+  return result;
+}
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index 869cb0f..cc43822 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -302,6 +302,22 @@ extern int rpl_lstat (const char *name, struct stat *buf);
    lstat (p, b))
 #endif

+#if @GNULIB_STAT@
+# if @REPLACE_STAT@
+/* We can't use the object-like #define stat rpl_stat, because of
+   struct stat.  This means that rpl_stat will not be used if the user
+   does (stat)(a,b).  Oh well.  */
+#  undef stat
+#  define stat(name, st) rpl_stat (name, st)
+extern int stat (const char *name, struct stat *buf);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef stat
+# define stat(p,b)                                                     \
+  (GL_LINK_WARNING ("stat is unportable - "                            \
+                   "use gnulib module stat for portability"),          \
+   stat (p, b))
+#endif

 #if @GNULIB_FCHMODAT@
 # if address@hidden@
diff --git a/m4/stat.m4 b/m4/stat.m4
new file mode 100644
index 0000000..9cc0b4a
--- /dev/null
+++ b/m4/stat.m4
@@ -0,0 +1,31 @@
+# serial 1
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_STAT],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_REQUIRE([gl_AC_DOS])
+  AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+  dnl mingw is the only known platform where stat(".") and stat("./") differ
+  AC_CACHE_CHECK([whether stat handles trailing slashes],
+      [gl_cv_func_stat_works],
+      [AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM(
+           [[#include <sys/stat.h>
+]], [[struct stat st; return stat (".", &st) != stat ("./", &st);]])],
+         [gl_cv_func_stat_works=yes], [gl_cv_func_stat_works=no],
+         [case $host_os in
+            mingw*) gl_cv_func_stat_works="guessing no";;
+            *) gl_cv_func_stat_works="guessing yes";;
+          esac])])
+  case $gl_cv_func_stat_works in
+    *yes) ;;
+    *) REPLACE_STAT=1
+       AC_LIBOBJ([stat]);;
+  esac
+])
diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4
index 4c01807..df7b238 100644
--- a/m4/sys_stat_h.m4
+++ b/m4/sys_stat_h.m4
@@ -1,4 +1,4 @@
-# sys_stat_h.m4 serial 15   -*- Autoconf -*-
+# sys_stat_h.m4 serial 16   -*- Autoconf -*-
 dnl Copyright (C) 2006-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,
@@ -56,6 +56,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
   GNULIB_MKDIRAT=0;   AC_SUBST([GNULIB_MKDIRAT])
   GNULIB_MKFIFOAT=0;  AC_SUBST([GNULIB_MKFIFOAT])
   GNULIB_MKNODAT=0;   AC_SUBST([GNULIB_MKNODAT])
+  GNULIB_STAT=0;      AC_SUBST([GNULIB_STAT])
   dnl Assume proper GNU behavior unless another module says otherwise.
   HAVE_FCHMODAT=1;    AC_SUBST([HAVE_FCHMODAT])
   HAVE_FSTATAT=1;     AC_SUBST([HAVE_FSTATAT])
@@ -67,4 +68,5 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
   REPLACE_FSTATAT=0;  AC_SUBST([REPLACE_FSTATAT])
   REPLACE_LSTAT=0;    AC_SUBST([REPLACE_LSTAT])
   REPLACE_MKDIR=0;    AC_SUBST([REPLACE_MKDIR])
+  REPLACE_STAT=0;     AC_SUBST([REPLACE_STAT])
 ])
diff --git a/modules/openat b/modules/openat
index 276882b..27e5c50 100644
--- a/modules/openat
+++ b/modules/openat
@@ -22,6 +22,7 @@ fchdir
 fcntl-h
 fdopendir
 gettext-h
+inline
 intprops
 lchown
 lstat
diff --git a/modules/stat b/modules/stat
new file mode 100644
index 0000000..9729b84
--- /dev/null
+++ b/modules/stat
@@ -0,0 +1,26 @@
+Description:
+stat(): query file information
+
+Files:
+lib/stat.c
+m4/dos.m4
+m4/stat.m4
+
+Depends-on:
+stdbool
+sys_stat
+
+configure.ac:
+gl_FUNC_STAT
+gl_SYS_STAT_MODULE_INDICATOR([stat])
+
+Makefile.am:
+
+Include:
+<sys/stat.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+Eric Blake
diff --git a/modules/stat-tests b/modules/stat-tests
new file mode 100644
index 0000000..3d31b52
--- /dev/null
+++ b/modules/stat-tests
@@ -0,0 +1,12 @@
+Files:
+tests/test-stat.c
+
+Depends-on:
+pathmax
+same-inode
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-stat
+check_PROGRAMS += test-stat
diff --git a/modules/sys_stat b/modules/sys_stat
index 0747c4f..34e01ab 100644
--- a/modules/sys_stat
+++ b/modules/sys_stat
@@ -33,6 +33,7 @@ sys/stat.h: sys_stat.in.h
              -e 's|@''GNULIB_MKDIRAT''@|$(GNULIB_MKDIRAT)|g' \
              -e 's|@''GNULIB_MKFIFOAT''@|$(GNULIB_MKFIFOAT)|g' \
              -e 's|@''GNULIB_MKNODAT''@|$(GNULIB_MKNODAT)|g' \
+             -e 's|@''GNULIB_STAT''@|$(GNULIB_STAT)|g' \
              -e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \
              -e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \
              -e 's|@''HAVE_LCHMOD''@|$(HAVE_LCHMOD)|g' \
@@ -44,6 +45,7 @@ sys/stat.h: sys_stat.in.h
              -e 's|@''REPLACE_FSTATAT''@|$(REPLACE_FSTATAT)|g' \
              -e 's|@''REPLACE_LSTAT''@|$(REPLACE_LSTAT)|g' \
              -e 's|@''REPLACE_MKDIR''@|$(REPLACE_MKDIR)|g' \
+             -e 's|@''REPLACE_STAT''@|$(REPLACE_STAT)|g' \
              -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
              < $(srcdir)/sys_stat.in.h; \
        } > address@hidden && \
diff --git a/tests/test-stat.c b/tests/test-stat.c
new file mode 100644
index 0000000..145edb5
--- /dev/null
+++ b/tests/test-stat.c
@@ -0,0 +1,79 @@
+/* Tests of stat.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Eric Blake <address@hidden>, 2009.  */
+
+#include <config.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "pathmax.h"
+#include "same-inode.h"
+
+#define ASSERT(expr) \
+  do                                                                         \
+    {                                                                        \
+      if (!(expr))                                                           \
+       {                                                                    \
+         fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__);  \
+         fflush (stderr);                                                   \
+         abort ();                                                          \
+       }                                                                    \
+    }                                                                        \
+  while (0)
+
+int
+main ()
+{
+  struct stat st1;
+  struct stat st2;
+  char cwd[PATH_MAX];
+
+  ASSERT (getcwd (cwd, PATH_MAX) == cwd);
+  ASSERT (stat (".", &st1) == 0);
+  ASSERT (stat ("./", &st2) == 0);
+  ASSERT (SAME_INODE (st1, st2));
+  ASSERT (stat (cwd, &st2) == 0);
+  ASSERT (SAME_INODE (st1, st2));
+  ASSERT (stat ("/", &st1) == 0);
+  ASSERT (stat ("///", &st2) == 0);
+  ASSERT (SAME_INODE (st1, st2));
+
+  errno = 0;
+  ASSERT (stat ("", &st1) == -1);
+  ASSERT (errno == ENOENT);
+  errno = 0;
+  ASSERT (stat ("nosuch", &st1) == -1);
+  ASSERT (errno == ENOENT);
+  errno = 0;
+  ASSERT (stat ("nosuch/", &st1) == -1);
+  ASSERT (errno == ENOENT);
+
+  ASSERT (close (creat ("test-stat.tmp", 0600)) == 0);
+  ASSERT (stat ("test-stat.tmp", &st1) == 0);
+  errno = 0;
+  ASSERT (stat ("test-stat.tmp/", &st1) == -1);
+  ASSERT (errno == ENOTDIR);
+  ASSERT (unlink ("test-stat.tmp") == 0);
+
+  return 0;
+}
-- 
1.6.4.2


>From b10c9750a2c9b9ddc7659d871592c5330eeb2df8 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Tue, 15 Sep 2009 17:08:39 -0600
Subject: [PATCH 2/3] stat: also work around Solaris 9 bug

* m4/stat.m4 (gl_FUNC_STAT): Detect Solaris bug.
* lib/stat.c (rpl_stat): Work around it.
* doc/posix-functions/stat.texi (stat): Update documentation.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog                     |    7 +++++++
 doc/posix-functions/stat.texi |    4 ++++
 lib/stat.c                    |   22 +++++++++++++++++-----
 m4/stat.m4                    |   38 ++++++++++++++++++++++++++++----------
 4 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c339f25..f109568 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2009-09-16  Eric Blake  <address@hidden>

+       stat: also work around Solaris 9 bug
+       * m4/stat.m4 (gl_FUNC_STAT): Detect Solaris bug.
+       * lib/stat.c (rpl_stat): Work around it.
+       * doc/posix-functions/stat.texi (stat): Update documentation.
+
+2009-09-16  Eric Blake  <address@hidden>
+
        stat: new module, for mingw bug
        * modules/stat: New file.
        * lib/stat.c: Likewise.
diff --git a/doc/posix-functions/stat.texi b/doc/posix-functions/stat.texi
index 3160cc7..72b3bc4 100644
--- a/doc/posix-functions/stat.texi
+++ b/doc/posix-functions/stat.texi
@@ -9,6 +9,10 @@ stat
 Portability problems fixed by Gnulib:
 @itemize
 @item
+On some platforms, @code{stat("file/",buf)} succeeds instead of
+failing with @code{ENOTDIR}.
+Solaris 9.
address@hidden
 On some platforms, @code{stat(".",buf)} and @code{stat("./",buf)} give
 different results:
 mingw.
diff --git a/lib/stat.c b/lib/stat.c
index 07aa323..9eb5738 100644
--- a/lib/stat.c
+++ b/lib/stat.c
@@ -27,16 +27,27 @@

 #undef stat

-/* For now, mingw is the only known platform where stat(".") and
-   stat("./") give different results.  Mingw stat has other bugs (such
-   as st_ino always being 0 on success) which this wrapper does not
-   work around.  But at least this implementation provides the ability
-   to emulate fchdir correctly.  */
+/* Store information about NAME into ST.  Work around bugs with
+   trailing slashes.  Mingw has other bugs (such as st_ino always
+   being 0 on success) which this wrapper does not work around.  But
+   at least this implementation provides the ability to emulate fchdir
+   correctly.  */

 int
 rpl_stat (char const *name, struct stat *st)
 {
   int result = stat (name, st);
+#if REPLACE_FUNC_STAT_FILE
+  /* Solaris 9 mistakenly succeeds when given a non-directory with a
+     trailing slash.  */
+  size_t len = strlen (name);
+  if (result == 0 && !S_ISDIR (st->st_mode) && ISSLASH (name[len - 1]))
+    {
+      result = -1;
+      errno = ENOTDIR;
+    }
+#endif /* REPLACE_FUNC_STAT_FILE */
+#if REPLACE_FUNC_STAT_DIR
   if (result == -1 && errno == ENOENT)
     {
       /* Due to mingw's oddities, there are some directories (like
@@ -74,5 +85,6 @@ rpl_stat (char const *name, struct stat *st)
             }
         }
     }
+#endif /* REPLACE_FUNC_STAT_DIR */
   return result;
 }
diff --git a/m4/stat.m4 b/m4/stat.m4
index 9cc0b4a..0a10de1 100644
--- a/m4/stat.m4
+++ b/m4/stat.m4
@@ -1,4 +1,4 @@
-# serial 1
+# serial 2

 # Copyright (C) 2009 Free Software Foundation, Inc.
 #
@@ -12,20 +12,38 @@ AC_DEFUN([gl_FUNC_STAT],
   AC_REQUIRE([gl_AC_DOS])
   AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
   dnl mingw is the only known platform where stat(".") and stat("./") differ
-  AC_CACHE_CHECK([whether stat handles trailing slashes],
-      [gl_cv_func_stat_works],
+  AC_CACHE_CHECK([whether stat handles trailing slashes on directories],
+      [gl_cv_func_stat_dir_slash],
       [AC_RUN_IFELSE(
          [AC_LANG_PROGRAM(
            [[#include <sys/stat.h>
 ]], [[struct stat st; return stat (".", &st) != stat ("./", &st);]])],
-         [gl_cv_func_stat_works=yes], [gl_cv_func_stat_works=no],
+         [gl_cv_func_stat_dir_slash=yes], [gl_cv_func_stat_dir_slash=no],
          [case $host_os in
-            mingw*) gl_cv_func_stat_works="guessing no";;
-            *) gl_cv_func_stat_works="guessing yes";;
+            mingw*) gl_cv_func_stat_dir_slash="guessing no";;
+            *) gl_cv_func_stat_dir_slash="guessing yes";;
           esac])])
-  case $gl_cv_func_stat_works in
-    *yes) ;;
-    *) REPLACE_STAT=1
-       AC_LIBOBJ([stat]);;
+  dnl Solaris 9 mistakenly succeeds on stat("file/")
+  AC_CACHE_CHECK([whether stat handles trailing slashes on files],
+      [gl_cv_func_stat_file_slash],
+      [touch conftest.tmp
+       AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM(
+           [[#include <sys/stat.h>
+]], [[struct stat st; return !stat ("conftest.tmp/", &st);]])],
+         [gl_cv_func_stat_file_slash=yes], [gl_cv_func_stat_file_slash=no],
+         [gl_cv_func_stat_file_slash="guessing no"])])
+  case $gl_cv_func_stat_dir_slash in
+    *no) REPLACE_STAT=1
+      AC_DEFINE([REPLACE_FUNC_STAT_DIR], [1], [Define to 1 if stat needs
+        help when passed a directory name with a trailing slash]);;
+  esac
+  case $gl_cv_func_stat_file_slash in
+    *no) REPLACE_STAT=1
+      AC_DEFINE([REPLACE_FUNC_STAT_FILE], [1], [Define to 1 if stat needs
+        help when passed a file name with a trailing slash]);;
   esac
+  if test $REPLACE_STAT = 1; then
+    AC_LIBOBJ([stat])
+  fi
 ])
-- 
1.6.4.2


>From 94af04bca598c292e2cc7ebee18d0bf52b44ab48 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Tue, 15 Sep 2009 14:43:14 -0600
Subject: [PATCH 3/3] stat: add as dependency to other modules

Modules that use stat but are not in this list don't trip any of
the bugs that the stat module fixes.
* modules/chown (Depends-on): Add stat.
* modules/euidaccess (Depends-on): Likewise.
* modules/fchdir (Depends-on): Likewise.
* modules/isdir (Depends-on): Likewise.
* modules/link (Depends-on): Likewise.
* modules/lstat (Depends-on): Likewise.
* modules/mkdir-p (Depends-on): Likewise.
* modules/modechange (Depends-on): Likewise.
* modules/open (Depends-on): Likewise.
* modules/readlink (Depends-on): Likewise.
* modules/same (Depends-on): Likewise.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog          |   17 +++++++++++++++++
 modules/chown      |    1 +
 modules/euidaccess |    1 +
 modules/fchdir     |    1 +
 modules/isdir      |    2 +-
 modules/link       |    1 +
 modules/lstat      |    1 +
 modules/mkdir-p    |    1 +
 modules/modechange |    1 +
 modules/open       |    1 +
 modules/readlink   |    1 +
 modules/same       |    1 +
 12 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f109568..fe5beb0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2009-09-16  Eric Blake  <address@hidden>

+       stat: add as dependency to other modules
+       Modules that use stat but are not in this list don't trip any of
+       the bugs that the stat module fixes.
+       * modules/chown (Depends-on): Add stat.
+       * modules/euidaccess (Depends-on): Likewise.
+       * modules/fchdir (Depends-on): Likewise.
+       * modules/isdir (Depends-on): Likewise.
+       * modules/link (Depends-on): Likewise.
+       * modules/lstat (Depends-on): Likewise.
+       * modules/mkdir-p (Depends-on): Likewise.
+       * modules/modechange (Depends-on): Likewise.
+       * modules/open (Depends-on): Likewise.
+       * modules/readlink (Depends-on): Likewise.
+       * modules/same (Depends-on): Likewise.
+
+2009-09-16  Eric Blake  <address@hidden>
+
        stat: also work around Solaris 9 bug
        * m4/stat.m4 (gl_FUNC_STAT): Detect Solaris bug.
        * lib/stat.c (rpl_stat): Work around it.
diff --git a/modules/chown b/modules/chown
index cf99210..88d0cd4 100644
--- a/modules/chown
+++ b/modules/chown
@@ -9,6 +9,7 @@ m4/chown.m4
 Depends-on:
 open
 unistd
+stat
 sys_stat

 configure.ac:
diff --git a/modules/euidaccess b/modules/euidaccess
index 47d9716..bf329c6 100644
--- a/modules/euidaccess
+++ b/modules/euidaccess
@@ -9,6 +9,7 @@ Depends-on:
 unistd
 extensions
 group-member
+stat
 sys_stat

 configure.ac:
diff --git a/modules/fchdir b/modules/fchdir
index 8a1cd1c..f525849 100644
--- a/modules/fchdir
+++ b/modules/fchdir
@@ -16,6 +16,7 @@ include_next
 malloc-posix
 open
 realloc-posix
+stat
 stdbool
 strdup-posix
 sys_stat
diff --git a/modules/isdir b/modules/isdir
index 09f5956..001546e 100644
--- a/modules/isdir
+++ b/modules/isdir
@@ -6,6 +6,7 @@ lib/isdir.c
 m4/isdir.m4

 Depends-on:
+stat

 configure.ac:
 gl_ISDIR
@@ -20,4 +21,3 @@ GPL

 Maintainer:
 Jim Meyering
-
diff --git a/modules/link b/modules/link
index 9492950..6a006c3 100644
--- a/modules/link
+++ b/modules/link
@@ -6,6 +6,7 @@ lib/link.c
 m4/link.m4

 Depends-on:
+stat
 strdup-posix
 sys_stat
 unistd
diff --git a/modules/lstat b/modules/lstat
index b0c8b44..e4eabb5 100644
--- a/modules/lstat
+++ b/modules/lstat
@@ -6,6 +6,7 @@ lib/lstat.c
 m4/lstat.m4

 Depends-on:
+stat
 sys_stat

 configure.ac:
diff --git a/modules/mkdir-p b/modules/mkdir-p
index 20e3a23..3b0abdf 100644
--- a/modules/mkdir-p
+++ b/modules/mkdir-p
@@ -17,6 +17,7 @@ lchown
 mkancesdirs
 quote
 savewd
+stat
 stat-macros
 stdbool
 sys_stat
diff --git a/modules/modechange b/modules/modechange
index 80d8b70..e58589a 100644
--- a/modules/modechange
+++ b/modules/modechange
@@ -8,6 +8,7 @@ lib/modechange.c
 m4/modechange.m4

 Depends-on:
+stat
 stat-macros
 stdbool
 sys_stat
diff --git a/modules/open b/modules/open
index 601e064..0b8b303 100644
--- a/modules/open
+++ b/modules/open
@@ -8,6 +8,7 @@ m4/mode_t.m4

 Depends-on:
 fcntl-h
+stat

 configure.ac:
 gl_FUNC_OPEN
diff --git a/modules/readlink b/modules/readlink
index 8e2a1de..eb32ef5 100644
--- a/modules/readlink
+++ b/modules/readlink
@@ -6,6 +6,7 @@ lib/readlink.c
 m4/readlink.m4

 Depends-on:
+stat
 unistd

 configure.ac:
diff --git a/modules/same b/modules/same
index b17d735..a6fc64f 100644
--- a/modules/same
+++ b/modules/same
@@ -12,6 +12,7 @@ xalloc
 error
 dirname
 same-inode
+stat
 stdbool
 memcmp

-- 
1.6.4.2







reply via email to

[Prev in Thread] Current Thread [Next in Thread]