diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2011-09-03 10:03:22 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2011-09-03 10:03:57 -0700 |
commit | e91216b238f2af78257bd943db0b22b289d172cc (patch) | |
tree | c62e37cf00e843f0a3d990cc4fb24610e2dcfe08 /lib/fstatat.c | |
parent | e4078c6f6eed0f441ab49d8b98f3812c20f7278d (diff) | |
download | gnulib-e91216b238f2af78257bd943db0b22b289d172cc.tar.gz |
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
<http://lists.gnu.org/archive/html/bug-tar/2011-09/msg00015.html>.
* lib/fstatat.c (FSTATAT_AT_FDCWD_0_BROKEN)
(LSTAT_FOLLOWS_SLASHED_SYMLINK): Default to 0.
(rpl_fstatat): Adjust so that it works around either (or both)
bugs if present.
* m4/openat.m4 (gl_FUNC_FSTATAT): Test for this fstatat bug.
Diffstat (limited to 'lib/fstatat.c')
-rw-r--r-- | lib/fstatat.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/fstatat.c b/lib/fstatat.c index a904e43262..f1bed737fb 100644 --- a/lib/fstatat.c +++ b/lib/fstatat.c @@ -46,19 +46,33 @@ orig_fstatat (int fd, char const *filename, struct stat *buf, int flags) # undef fstatat +# ifndef FSTATAT_AT_FDCWD_0_BROKEN +# define FSTATAT_AT_FDCWD_0_BROKEN 0 +# endif + +# ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK +# define LSTAT_FOLLOWS_SLASHED_SYMLINK 0 +# endif + /* fstatat should always follow symbolic links that end in /, but on Solaris 9 it doesn't if AT_SYMLINK_NOFOLLOW is specified. Likewise, trailing slash on a non-directory should be an error. These are the same problems that lstat.c and stat.c address, so - solve it in a similar way. */ + solve it in a similar way. + + AIX 7.1 fstatat (AT_FDCWD, ..., 0) always fails, which is a bug. + Work around this bug if FSTATAT_AT_FDCWD_0_BROKEN is nonzero. */ int rpl_fstatat (int fd, char const *file, struct stat *st, int flag) { - int result = orig_fstatat (fd, file, st, flag); + int result = + (FSTATAT_AT_FDCWD_0_BROKEN && fd == AT_FDCWD && flag == 0 + ? stat (file, st) + : orig_fstatat (fd, file, st, flag)); size_t len; - if (result != 0) + if (LSTAT_FOLLOWS_SLASHED_SYMLINK || result != 0) return result; len = strlen (file); if (flag & AT_SYMLINK_NOFOLLOW) |