summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2009-11-07 16:59:11 -0700
committerEric Blake <ebb9@byu.net>2009-11-09 06:16:05 -0700
commit349396ebfcce12ee8f927fedf82067414c427093 (patch)
treeebc0f680a8f44e92daa6ea293b9b4c7994a0caee /tests
parent6553be82a4a522e50ece1a430e82a9b1dfd0f471 (diff)
downloadgnulib-349396ebfcce12ee8f927fedf82067414c427093.tar.gz
stat: detect FreeBSD bug
Like Solaris 9, FreeBSD 7.2 mistakenly allows stat("link-to-file/"). Unlike Solaris, it correctly forbids stat("file/"). A number of interfaces are affected (such as utimes), but replacing stat is enough to catch several by reusing the Solaris 9 fixes. * m4/stat.m4 (gl_FUNC_STAT): Also detect FreeBSD bug with slash on symlink. * doc/posix-functions/stat.texi (stat): Document the bug. * tests/test-stat.h (test_stat_func): Add argument. * tests/test-stat.c (main): Adjust caller. * tests/test-fstatat.c (main): Likewise. * modules/stat-tests (Depends-on): Add stdbool, symlink. Reported by Jim Meyering. Signed-off-by: Eric Blake <ebb9@byu.net>
Diffstat (limited to 'tests')
-rw-r--r--tests/test-fstatat.c18
-rw-r--r--tests/test-stat.c13
-rw-r--r--tests/test-stat.h45
3 files changed, 59 insertions, 17 deletions
diff --git a/tests/test-fstatat.c b/tests/test-fstatat.c
index ad5434e081..e965997b29 100644
--- a/tests/test-fstatat.c
+++ b/tests/test-fstatat.c
@@ -35,11 +35,11 @@
do \
{ \
if (!(expr)) \
- { \
- fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
- fflush (stderr); \
- abort (); \
- } \
+ { \
+ fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
+ fflush (stderr); \
+ abort (); \
+ } \
} \
while (0)
@@ -68,11 +68,11 @@ int
main (void)
{
int result;
- ASSERT (test_stat_func (do_stat) == 0);
- result = test_lstat_func (do_lstat, false);
+ result = test_stat_func (do_stat, false);
+ ASSERT (test_lstat_func (do_lstat, false) == result);
dfd = open (".", O_RDONLY);
ASSERT (0 <= dfd);
- ASSERT (test_stat_func (do_stat) == 0);
+ ASSERT (test_stat_func (do_stat, false) == result);
ASSERT (test_lstat_func (do_lstat, false) == result);
ASSERT (close (dfd) == 0);
@@ -80,6 +80,6 @@ main (void)
if (result == 77)
fputs ("skipping test: symlinks not supported on this file system\n",
- stderr);
+ stderr);
return result;
}
diff --git a/tests/test-stat.c b/tests/test-stat.c
index 61a9d90182..fc11731467 100644
--- a/tests/test-stat.c
+++ b/tests/test-stat.c
@@ -22,6 +22,7 @@
#include <fcntl.h>
#include <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -33,11 +34,11 @@
do \
{ \
if (!(expr)) \
- { \
- fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
- fflush (stderr); \
- abort (); \
- } \
+ { \
+ fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
+ fflush (stderr); \
+ abort (); \
+ } \
} \
while (0)
@@ -56,5 +57,5 @@ do_stat (char const *name, struct stat *st)
int
main (void)
{
- return test_stat_func (do_stat);
+ return test_stat_func (do_stat, true);
}
diff --git a/tests/test-stat.h b/tests/test-stat.h
index 17bb43fe47..8f7897cabb 100644
--- a/tests/test-stat.h
+++ b/tests/test-stat.h
@@ -19,10 +19,11 @@
/* This file is designed to test both stat(n,buf) and
fstatat(AT_FDCWD,n,buf,0). FUNC is the function to test. Assumes
that BASE and ASSERT are already defined, and that appropriate
- headers are already included. */
+ headers are already included. If PRINT, warn before skipping
+ symlink tests with status 77. */
static int
-test_stat_func (int (*func) (char const *, struct stat *))
+test_stat_func (int (*func) (char const *, struct stat *), bool print)
{
struct stat st1;
struct stat st2;
@@ -53,7 +54,47 @@ test_stat_func (int (*func) (char const *, struct stat *))
errno = 0;
ASSERT (func (BASE "file/", &st1) == -1);
ASSERT (errno == ENOTDIR);
+
+ /* Now for some symlink tests, where supported. We set up:
+ link1 -> directory
+ link2 -> file
+ link3 -> dangling
+ link4 -> loop
+ then test behavior with trailing slash.
+ */
+ if (symlink (".", BASE "link1") != 0)
+ {
+ ASSERT (unlink (BASE "file") == 0);
+ if (print)
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ return 77;
+ }
+ ASSERT (symlink (BASE "file", BASE "link2") == 0);
+ ASSERT (symlink (BASE "nosuch", BASE "link3") == 0);
+ ASSERT (symlink (BASE "link4", BASE "link4") == 0);
+
+ ASSERT (func (BASE "link1/", &st1) == 0);
+ ASSERT (S_ISDIR (st1.st_mode));
+
+ errno = 0;
+ ASSERT (func (BASE "link2/", &st1) == -1);
+ ASSERT (errno == ENOTDIR);
+
+ errno = 0;
+ ASSERT (func (BASE "link3/", &st1) == -1);
+ ASSERT (errno == ENOENT);
+
+ errno = 0;
+ ASSERT (func (BASE "link4/", &st1) == -1);
+ ASSERT (errno == ELOOP);
+
+ /* Cleanup. */
ASSERT (unlink (BASE "file") == 0);
+ ASSERT (unlink (BASE "link1") == 0);
+ ASSERT (unlink (BASE "link2") == 0);
+ ASSERT (unlink (BASE "link3") == 0);
+ ASSERT (unlink (BASE "link4") == 0);
return 0;
}