Mercurial > hg > octave-nkf > gnulib-hg
changeset 12037:eb6b9da995d7
stat: fix Solaris 9 bug
stat("file/",buf) mistakenly succeeded.
* m4/stat.m4 (gl_FUNC_STAT): Detect Solaris 9 bug with trailing
slash.
* lib/stat.c (rpl_stat): Work around it.
* doc/posix-functions/stat.texi (stat): Update documentation.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Tue, 15 Sep 2009 17:08:39 -0600 |
parents | 1762604ec0a7 |
children | ac2a6371d78c |
files | ChangeLog doc/posix-functions/stat.texi lib/stat.c m4/stat.m4 |
diffstat | 4 files changed, 73 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2009-09-19 Eric Blake <ebb9@byu.net> + stat: fix Solaris 9 bug + * m4/stat.m4 (gl_FUNC_STAT): Detect Solaris 9 bug with trailing + slash. + * lib/stat.c (rpl_stat): Work around it. + * doc/posix-functions/stat.texi (stat): Update documentation. + stat: new module, for mingw bug * modules/stat: New file. * lib/stat.c: Likewise.
--- a/doc/posix-functions/stat.texi +++ b/doc/posix-functions/stat.texi @@ -9,6 +9,10 @@ Portability problems fixed by Gnulib: @itemize @item +On some platforms, @code{stat("file/",buf)} succeeds instead of +failing with @code{ENOTDIR}. +Solaris 9. +@item On some platforms, @code{stat(".",buf)} and @code{stat("./",buf)} give different results: mingw.
--- a/lib/stat.c +++ b/lib/stat.c @@ -18,6 +18,19 @@ #include <config.h> +/* Get the original definition of stat. It might be defined as a macro. */ +#define __need_system_sys_stat_h +#include <sys/types.h> +#include <sys/stat.h> +#undef __need_system_sys_stat_h + +static inline int +orig_stat (const char *filename, struct stat *buf) +{ + return stat (filename, buf); +} + +/* Specification. */ #include <sys/stat.h> #include <errno.h> @@ -25,18 +38,30 @@ #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. */ +/* 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); + int result = orig_stat (name, st); +#if REPLACE_FUNC_STAT_FILE + /* Solaris 9 mistakenly succeeds when given a non-directory with a + trailing slash. */ + if (result == 0 && !S_ISDIR (st->st_mode)) + { + size_t len = strlen (name); + if (ISSLASH (name[len - 1])) + { + errno = ENOTDIR; + return -1; + } + } +#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 @@ -66,7 +91,7 @@ } else fixed_name[len++] = '/'; - result = stat (fixed_name, st); + result = orig_stat (fixed_name, st); if (result == 0 && check_dir && !S_ISDIR (st->st_mode)) { result = -1; @@ -74,5 +99,6 @@ } } } +#endif /* REPLACE_FUNC_STAT_DIR */ return result; }
--- 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_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 ])