From bcac7cc32b1c42db4fdc47a3c5a5b284a1d16850 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 13 Nov 2010 00:39:03 +0100 Subject: [PATCH] rename test: Add comments. * tests/test-rename.h (test_rename): Add structure and comments. --- ChangeLog | 5 + tests/test-rename.h | 1008 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 738 insertions(+), 275 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97cebc2ff..e2bd35cfa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-13 Bruno Haible + + rename test: Add comments. + * tests/test-rename.h (test_rename): Add structure and comments. + 2010-11-13 Eric Blake maintainer-makefile: cover a few more files diff --git a/tests/test-rename.h b/tests/test-rename.h index 9a3f4ecf1..97530524a 100644 --- a/tests/test-rename.h +++ b/tests/test-rename.h @@ -31,168 +31,404 @@ test_rename (int (*func) (char const *, char const *), bool print) ASSERT (close (fd) == 0); ASSERT (mkdir (BASE "dir", 0700) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + */ + /* Obvious errors. */ - errno = 0; /* Missing source. */ - ASSERT (func (BASE "missing", BASE "missing") == -1); - ASSERT (errno == ENOENT); - errno = 0; - ASSERT (func (BASE "missing/", BASE "missing") == -1); - ASSERT (errno == ENOENT); - errno = 0; - ASSERT (func (BASE "missing", BASE "missing/") == -1); - ASSERT (errno == ENOENT); - errno = 0; /* Empty operand. */ - ASSERT (func ("", BASE "missing") == -1); - ASSERT (errno == ENOENT); - errno = 0; - ASSERT (func (BASE "file", "") == -1); - ASSERT (errno == ENOENT); - errno = 0; - ASSERT (func (BASE "", "") == -1); - ASSERT (errno == ENOENT); + { /* Missing source. */ + { + errno = 0; + ASSERT (func (BASE "missing", BASE "missing") == -1); + ASSERT (errno == ENOENT); + } + { + errno = 0; + ASSERT (func (BASE "missing/", BASE "missing") == -1); + ASSERT (errno == ENOENT); + } + { + errno = 0; + ASSERT (func (BASE "missing", BASE "missing/") == -1); + ASSERT (errno == ENOENT); + } + } + { /* Empty operand. */ + { + errno = 0; + ASSERT (func ("", BASE "missing") == -1); + ASSERT (errno == ENOENT); + } + { + errno = 0; + ASSERT (func (BASE "file", "") == -1); + ASSERT (errno == ENOENT); + } + { + errno = 0; + ASSERT (func (BASE "", "") == -1); + ASSERT (errno == ENOENT); + } + } /* Files. */ - errno = 0; /* Trailing slash. */ - ASSERT (func (BASE "file", BASE "file2/") == -1); - ASSERT (errno == ENOENT || errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "file/", BASE "file2") == -1); - ASSERT (errno == ENOTDIR); - errno = 0; - ASSERT (stat (BASE "file2", &st) == -1); - ASSERT (errno == ENOENT); - ASSERT (func (BASE "file", BASE "file2") == 0); /* Simple rename. */ - errno = 0; - ASSERT (stat (BASE "file", &st) == -1); - ASSERT (errno == ENOENT); - memset (&st, 0, sizeof st); - ASSERT (stat (BASE "file2", &st) == 0); - ASSERT (st.st_size == 2); - ASSERT (close (creat (BASE "file", 0600)) == 0); /* Overwrite. */ - errno = 0; - ASSERT (func (BASE "file2", BASE "file/") == -1); - ASSERT (errno == ENOTDIR); - ASSERT (func (BASE "file2", BASE "file") == 0); - memset (&st, 0, sizeof st); - ASSERT (stat (BASE "file", &st) == 0); - ASSERT (st.st_size == 2); - errno = 0; - ASSERT (stat (BASE "file2", &st) == -1); - ASSERT (errno == ENOENT); + + { /* Trailing slash. */ + { + errno = 0; + ASSERT (func (BASE "file", BASE "file2/") == -1); + ASSERT (errno == ENOENT || errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "file/", BASE "file2") == -1); + ASSERT (errno == ENOTDIR); + } + { + errno = 0; + ASSERT (stat (BASE "file2", &st) == -1); + ASSERT (errno == ENOENT); + } + } + { /* Simple rename. */ + ASSERT (func (BASE "file", BASE "file2") == 0); + errno = 0; + ASSERT (stat (BASE "file", &st) == -1); + ASSERT (errno == ENOENT); + memset (&st, 0, sizeof st); + ASSERT (stat (BASE "file2", &st) == 0); + ASSERT (st.st_size == 2); + } + /* Files present here: + {BASE}file2 + {BASE}dir/ + */ + { /* Overwrite. */ + ASSERT (close (creat (BASE "file", 0600)) == 0); + errno = 0; + ASSERT (func (BASE "file2", BASE "file/") == -1); + ASSERT (errno == ENOTDIR); + ASSERT (func (BASE "file2", BASE "file") == 0); + memset (&st, 0, sizeof st); + ASSERT (stat (BASE "file", &st) == 0); + ASSERT (st.st_size == 2); + errno = 0; + ASSERT (stat (BASE "file2", &st) == -1); + ASSERT (errno == ENOENT); + } + /* Files present here: + {BASE}file + {BASE}dir/ + */ /* Directories. */ - ASSERT (func (BASE "dir", BASE "dir2/") == 0); /* Simple rename. */ - errno = 0; - ASSERT (stat (BASE "dir", &st) == -1); - ASSERT (errno == ENOENT); - ASSERT (stat (BASE "dir2", &st) == 0); - ASSERT (func (BASE "dir2/", BASE "dir") == 0); - ASSERT (stat (BASE "dir", &st) == 0); - errno = 0; - ASSERT (stat (BASE "dir2", &st) == -1); - ASSERT (errno == ENOENT); - ASSERT (func (BASE "dir", BASE "dir2") == 0); - errno = 0; - ASSERT (stat (BASE "dir", &st) == -1); - ASSERT (errno == ENOENT); - ASSERT (stat (BASE "dir2", &st) == 0); - ASSERT (mkdir (BASE "dir", 0700) == 0); /* Empty onto empty. */ - ASSERT (func (BASE "dir2", BASE "dir") == 0); - ASSERT (mkdir (BASE "dir2", 0700) == 0); - ASSERT (func (BASE "dir2", BASE "dir/") == 0); - ASSERT (mkdir (BASE "dir2", 0700) == 0); - ASSERT (func (BASE "dir2/", BASE "dir") == 0); - ASSERT (mkdir (BASE "dir2", 0700) == 0); - ASSERT (close (creat (BASE "dir/file", 0600)) == 0); /* Empty onto full. */ - errno = 0; - ASSERT (func (BASE "dir2", BASE "dir") == -1); - ASSERT (errno == EEXIST || errno == ENOTEMPTY); - errno = 0; - ASSERT (func (BASE "dir2/", BASE "dir") == -1); - ASSERT (errno == EEXIST || errno == ENOTEMPTY); - errno = 0; - ASSERT (func (BASE "dir2", BASE "dir/") == -1); - ASSERT (errno == EEXIST || errno == ENOTEMPTY); - ASSERT (func (BASE "dir", BASE "dir2") == 0); /* Full onto empty. */ - errno = 0; - ASSERT (stat (BASE "dir", &st) == -1); - ASSERT (errno == ENOENT); - ASSERT (stat (BASE "dir2/file", &st) == 0); - ASSERT (mkdir (BASE "dir", 0700) == 0); - ASSERT (func (BASE "dir2/", BASE "dir") == 0); - ASSERT (stat (BASE "dir/file", &st) == 0); - errno = 0; - ASSERT (stat (BASE "dir2", &st) == -1); - ASSERT (errno == ENOENT); - ASSERT (mkdir (BASE "dir2", 0700) == 0); - ASSERT (func (BASE "dir", BASE "dir2/") == 0); - errno = 0; - ASSERT (stat (BASE "dir", &st) == -1); - ASSERT (errno == ENOENT); - ASSERT (stat (BASE "dir2/file", &st) == 0); - ASSERT (unlink (BASE "dir2/file") == 0); - errno = 0; /* Reject trailing dot. */ - ASSERT (func (BASE "dir2", BASE "dir/.") == -1); - ASSERT (errno == EINVAL || errno == ENOENT); - ASSERT (mkdir (BASE "dir", 0700) == 0); - errno = 0; - ASSERT (func (BASE "dir2", BASE "dir/.") == -1); - ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR - || errno == ENOTEMPTY); - errno = 0; - ASSERT (func (BASE "dir2/.", BASE "dir") == -1); - ASSERT (errno == EINVAL || errno == EBUSY); - ASSERT (rmdir (BASE "dir") == 0); - errno = 0; - ASSERT (func (BASE "dir2", BASE "dir/.//") == -1); - ASSERT (errno == EINVAL || errno == ENOENT); - ASSERT (mkdir (BASE "dir", 0700) == 0); - errno = 0; - ASSERT (func (BASE "dir2", BASE "dir/.//") == -1); - ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR - || errno == ENOTEMPTY); - errno = 0; - ASSERT (func (BASE "dir2/.//", BASE "dir") == -1); - ASSERT (errno == EINVAL || errno == EBUSY); - ASSERT (rmdir (BASE "dir2") == 0); - errno = 0; /* Move into subdir. */ - ASSERT (func (BASE "dir", BASE "dir/sub") == -1); - ASSERT (errno == EINVAL || errno == EACCES); - errno = 0; - ASSERT (stat (BASE "dir/sub", &st) == -1); - ASSERT (errno == ENOENT); - ASSERT (mkdir (BASE "dir/sub", 0700) == 0); - errno = 0; - ASSERT (func (BASE "dir", BASE "dir/sub") == -1); - ASSERT (errno == EINVAL); - ASSERT (stat (BASE "dir/sub", &st) == 0); - ASSERT (rmdir (BASE "dir/sub") == 0); + + { /* Simple rename. */ + { + ASSERT (func (BASE "dir", BASE "dir2/") == 0); + errno = 0; + ASSERT (stat (BASE "dir", &st) == -1); + ASSERT (errno == ENOENT); + ASSERT (stat (BASE "dir2", &st) == 0); + } + /* Files present here: + {BASE}file + {BASE}dir2/ + */ + { + ASSERT (func (BASE "dir2/", BASE "dir") == 0); + ASSERT (stat (BASE "dir", &st) == 0); + errno = 0; + ASSERT (stat (BASE "dir2", &st) == -1); + ASSERT (errno == ENOENT); + } + /* Files present here: + {BASE}file + {BASE}dir/ + */ + { + ASSERT (func (BASE "dir", BASE "dir2") == 0); + errno = 0; + ASSERT (stat (BASE "dir", &st) == -1); + ASSERT (errno == ENOENT); + ASSERT (stat (BASE "dir2", &st) == 0); + } + /* Files present here: + {BASE}file + {BASE}dir2/ + */ + { /* Empty onto empty. */ + ASSERT (mkdir (BASE "dir", 0700) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir2/ + */ + ASSERT (func (BASE "dir2", BASE "dir") == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + */ + ASSERT (mkdir (BASE "dir2", 0700) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir2/ + */ + ASSERT (func (BASE "dir2", BASE "dir/") == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + */ + ASSERT (mkdir (BASE "dir2", 0700) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir2/ + */ + ASSERT (func (BASE "dir2/", BASE "dir") == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + */ + ASSERT (mkdir (BASE "dir2", 0700) == 0); + } + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir2/ + */ + { /* Empty onto full. */ + ASSERT (close (creat (BASE "dir/file", 0600)) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir/file + {BASE}dir2/ + */ + { + errno = 0; + ASSERT (func (BASE "dir2", BASE "dir") == -1); + ASSERT (errno == EEXIST || errno == ENOTEMPTY); + } + { + errno = 0; + ASSERT (func (BASE "dir2/", BASE "dir") == -1); + ASSERT (errno == EEXIST || errno == ENOTEMPTY); + } + { + errno = 0; + ASSERT (func (BASE "dir2", BASE "dir/") == -1); + ASSERT (errno == EEXIST || errno == ENOTEMPTY); + } + } + { /* Full onto empty. */ + ASSERT (func (BASE "dir", BASE "dir2") == 0); + errno = 0; + ASSERT (stat (BASE "dir", &st) == -1); + ASSERT (errno == ENOENT); + ASSERT (stat (BASE "dir2/file", &st) == 0); + /* Files present here: + {BASE}file + {BASE}dir2/ + {BASE}dir2/file + */ + ASSERT (mkdir (BASE "dir", 0700) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir2/ + {BASE}dir2/file + */ + { + ASSERT (func (BASE "dir2/", BASE "dir") == 0); + ASSERT (stat (BASE "dir/file", &st) == 0); + errno = 0; + ASSERT (stat (BASE "dir2", &st) == -1); + ASSERT (errno == ENOENT); + } + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir/file + */ + ASSERT (mkdir (BASE "dir2", 0700) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir/file + {BASE}dir2/ + */ + { + ASSERT (func (BASE "dir", BASE "dir2/") == 0); + errno = 0; + ASSERT (stat (BASE "dir", &st) == -1); + ASSERT (errno == ENOENT); + ASSERT (stat (BASE "dir2/file", &st) == 0); + } + /* Files present here: + {BASE}file + {BASE}dir2/ + {BASE}dir2/file + */ + ASSERT (unlink (BASE "dir2/file") == 0); + } + /* Files present here: + {BASE}file + {BASE}dir2/ + */ + { /* Reject trailing dot. */ + { + errno = 0; + ASSERT (func (BASE "dir2", BASE "dir/.") == -1); + ASSERT (errno == EINVAL || errno == ENOENT); + } + ASSERT (mkdir (BASE "dir", 0700) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir2/ + */ + { + errno = 0; + ASSERT (func (BASE "dir2", BASE "dir/.") == -1); + ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR + || errno == ENOTEMPTY); + } + { + errno = 0; + ASSERT (func (BASE "dir2/.", BASE "dir") == -1); + ASSERT (errno == EINVAL || errno == EBUSY); + } + ASSERT (rmdir (BASE "dir") == 0); + /* Files present here: + {BASE}file + {BASE}dir2/ + */ + { + errno = 0; + ASSERT (func (BASE "dir2", BASE "dir/.//") == -1); + ASSERT (errno == EINVAL || errno == ENOENT); + } + ASSERT (mkdir (BASE "dir", 0700) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir2/ + */ + { + errno = 0; + ASSERT (func (BASE "dir2", BASE "dir/.//") == -1); + ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR + || errno == ENOTEMPTY); + } + { + errno = 0; + ASSERT (func (BASE "dir2/.//", BASE "dir") == -1); + ASSERT (errno == EINVAL || errno == EBUSY); + } + ASSERT (rmdir (BASE "dir2") == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + */ + } + { /* Move into subdir. */ + { + errno = 0; + ASSERT (func (BASE "dir", BASE "dir/sub") == -1); + ASSERT (errno == EINVAL || errno == EACCES); + } + { + errno = 0; + ASSERT (stat (BASE "dir/sub", &st) == -1); + ASSERT (errno == ENOENT); + } + ASSERT (mkdir (BASE "dir/sub", 0700) == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir/sub/ + */ + { + errno = 0; + ASSERT (func (BASE "dir", BASE "dir/sub") == -1); + ASSERT (errno == EINVAL); + ASSERT (stat (BASE "dir/sub", &st) == 0); + } + ASSERT (rmdir (BASE "dir/sub") == 0); + } + } + /* Files present here: + {BASE}file + {BASE}dir/ + */ /* Mixing file and directory. */ - errno = 0; /* File onto dir. */ - ASSERT (func (BASE "file", BASE "dir") == -1); - ASSERT (errno == EISDIR || errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "file", BASE "dir/") == -1); - ASSERT (errno == EISDIR || errno == ENOTDIR); - errno = 0; /* Dir onto file. */ - ASSERT (func (BASE "dir", BASE "file") == -1); - ASSERT (errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "dir/", BASE "file") == -1); - ASSERT (errno == ENOTDIR); + + { + { /* File onto dir. */ + { + errno = 0; + ASSERT (func (BASE "file", BASE "dir") == -1); + ASSERT (errno == EISDIR || errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "file", BASE "dir/") == -1); + ASSERT (errno == EISDIR || errno == ENOTDIR); + } + } + { /* Dir onto file. */ + { + errno = 0; + ASSERT (func (BASE "dir", BASE "file") == -1); + ASSERT (errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "dir/", BASE "file") == -1); + ASSERT (errno == ENOTDIR); + } + } + } /* Hard links. */ - ASSERT (func (BASE "file", BASE "file") == 0); /* File onto self. */ - memset (&st, 0, sizeof st); - ASSERT (stat (BASE "file", &st) == 0); - ASSERT (st.st_size == 2); - ASSERT (func (BASE "dir", BASE "dir") == 0); /* Empty dir onto self. */ - ASSERT (stat (BASE "dir", &st) == 0); + + { /* File onto self. */ + ASSERT (func (BASE "file", BASE "file") == 0); + memset (&st, 0, sizeof st); + ASSERT (stat (BASE "file", &st) == 0); + ASSERT (st.st_size == 2); + } + /* Files present here: + {BASE}file + {BASE}dir/ + */ + { /* Empty dir onto self. */ + ASSERT (func (BASE "dir", BASE "dir") == 0); + ASSERT (stat (BASE "dir", &st) == 0); + } + /* Files present here: + {BASE}file + {BASE}dir/ + */ ASSERT (close (creat (BASE "dir/file", 0600)) == 0); - ASSERT (func (BASE "dir", BASE "dir") == 0); /* Full dir onto self. */ + /* Files present here: + {BASE}file + {BASE}dir/ + {BASE}dir/file + */ + { /* Full dir onto self. */ + ASSERT (func (BASE "dir", BASE "dir") == 0); + } ASSERT (unlink (BASE "dir/file") == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + */ { /* Not all file systems support link. Mingw doesn't have reliable st_nlink on hard links, but our implementation does @@ -234,16 +470,33 @@ test_rename (int (*func) (char const *, char const *), bool print) } ASSERT (ret == 0); } - ASSERT (func (BASE "file", BASE "file2") == 0); /* File onto hard link. */ - memset (&st, 0, sizeof st); - ASSERT (stat (BASE "file", &st) == 0); - ASSERT (st.st_size == 2); - memset (&st, 0, sizeof st); - ASSERT (stat (BASE "file2", &st) == 0); - ASSERT (st.st_size == 2); + /* Files present here: + {BASE}file + {BASE}file2 (hard link to file) + {BASE}dir/ + */ + { /* File onto hard link. */ + ASSERT (func (BASE "file", BASE "file2") == 0); + memset (&st, 0, sizeof st); + ASSERT (stat (BASE "file", &st) == 0); + ASSERT (st.st_size == 2); + memset (&st, 0, sizeof st); + ASSERT (stat (BASE "file2", &st) == 0); + ASSERT (st.st_size == 2); + } + /* Files present here: + {BASE}file + {BASE}file2 + {BASE}dir/ + */ ASSERT (unlink (BASE "file2") == 0); + /* Files present here: + {BASE}file + {BASE}dir/ + */ /* Symlinks. */ + if (symlink (BASE "file", BASE "link1")) { if (print) @@ -253,118 +506,297 @@ test_rename (int (*func) (char const *, char const *), bool print) ASSERT (rmdir (BASE "dir") == 0); return 77; } - ASSERT (func (BASE "link1", BASE "link2") == 0); /* Simple rename. */ - ASSERT (stat (BASE "file", &st) == 0); - errno = 0; - ASSERT (lstat (BASE "link1", &st) == -1); - ASSERT (errno == ENOENT); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "link2", &st) == 0); - ASSERT (S_ISLNK (st.st_mode)); - ASSERT (symlink (BASE "nowhere", BASE "link1") == 0); /* Overwrite. */ - ASSERT (func (BASE "link2", BASE "link1") == 0); - memset (&st, 0, sizeof st); - ASSERT (stat (BASE "link1", &st) == 0); - ASSERT (st.st_size == 2); - errno = 0; - ASSERT (lstat (BASE "link2", &st) == -1); - ASSERT (errno == ENOENT); - ASSERT (symlink (BASE "link2", BASE "link2") == 0); /* Symlink loop. */ - ASSERT (func (BASE "link2", BASE "link2") == 0); - errno = 0; - ASSERT (func (BASE "link2/", BASE "link2") == -1); - ASSERT (errno == ELOOP || errno == ENOTDIR); - ASSERT (func (BASE "link2", BASE "link3") == 0); - ASSERT (unlink (BASE "link3") == 0); - ASSERT (symlink (BASE "nowhere", BASE "link2") == 0); /* Dangling link. */ - ASSERT (func (BASE "link2", BASE "link3") == 0); - errno = 0; - ASSERT (lstat (BASE "link2", &st) == -1); - ASSERT (errno == ENOENT); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "link3", &st) == 0); - errno = 0; /* Trailing slash on dangling. */ - ASSERT (func (BASE "link3/", BASE "link2") == -1); - ASSERT (errno == ENOENT || errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "link3", BASE "link2/") == -1); - ASSERT (errno == ENOENT || errno == ENOTDIR); - errno = 0; - ASSERT (lstat (BASE "link2", &st) == -1); - ASSERT (errno == ENOENT); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "link3", &st) == 0); - errno = 0; /* Trailing slash on link to file. */ - ASSERT (func (BASE "link1/", BASE "link2") == -1); - ASSERT (errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "link1", BASE "link3/") == -1); - ASSERT (errno == ENOENT || errno == ENOTDIR); + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}dir/ + */ + { /* Simple rename. */ + ASSERT (func (BASE "link1", BASE "link2") == 0); + ASSERT (stat (BASE "file", &st) == 0); + errno = 0; + ASSERT (lstat (BASE "link1", &st) == -1); + ASSERT (errno == ENOENT); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "link2", &st) == 0); + ASSERT (S_ISLNK (st.st_mode)); + } + /* Files present here: + {BASE}file + {BASE}link2 -> {BASE}file + {BASE}dir/ + */ + { /* Overwrite. */ + ASSERT (symlink (BASE "nowhere", BASE "link1") == 0); + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}nowhere + {BASE}link2 -> {BASE}file + {BASE}dir/ + */ + { + ASSERT (func (BASE "link2", BASE "link1") == 0); + memset (&st, 0, sizeof st); + ASSERT (stat (BASE "link1", &st) == 0); + ASSERT (st.st_size == 2); + errno = 0; + ASSERT (lstat (BASE "link2", &st) == -1); + ASSERT (errno == ENOENT); + } + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}dir/ + */ + { /* Symlink loop. */ + ASSERT (symlink (BASE "link2", BASE "link2") == 0); + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link2 -> {BASE}link2 + {BASE}dir/ + */ + { + ASSERT (func (BASE "link2", BASE "link2") == 0); + } + { + errno = 0; + ASSERT (func (BASE "link2/", BASE "link2") == -1); + ASSERT (errno == ELOOP || errno == ENOTDIR); + } + ASSERT (func (BASE "link2", BASE "link3") == 0); + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link3 -> {BASE}link2 + {BASE}dir/ + */ + ASSERT (unlink (BASE "link3") == 0); + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}dir/ + */ + { /* Dangling link. */ + ASSERT (symlink (BASE "nowhere", BASE "link2") == 0); + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link2 -> {BASE}nowhere + {BASE}dir/ + */ + { + ASSERT (func (BASE "link2", BASE "link3") == 0); + errno = 0; + ASSERT (lstat (BASE "link2", &st) == -1); + ASSERT (errno == ENOENT); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "link3", &st) == 0); + } + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link3 -> {BASE}nowhere + {BASE}dir/ + */ + { /* Trailing slash on dangling. */ + { + errno = 0; + ASSERT (func (BASE "link3/", BASE "link2") == -1); + ASSERT (errno == ENOENT || errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "link3", BASE "link2/") == -1); + ASSERT (errno == ENOENT || errno == ENOTDIR); + } + { + errno = 0; + ASSERT (lstat (BASE "link2", &st) == -1); + ASSERT (errno == ENOENT); + } + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "link3", &st) == 0); + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link3 -> {BASE}nowhere + {BASE}dir/ + */ + { /* Trailing slash on link to file. */ + { + errno = 0; + ASSERT (func (BASE "link1/", BASE "link2") == -1); + ASSERT (errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "link1", BASE "link3/") == -1); + ASSERT (errno == ENOENT || errno == ENOTDIR); + } + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link3 -> {BASE}nowhere + {BASE}dir/ + */ /* Mixing symlink and file. */ - ASSERT (close (creat (BASE "file2", 0600)) == 0); /* File onto link. */ - ASSERT (func (BASE "file2", BASE "link3") == 0); - errno = 0; - ASSERT (stat (BASE "file2", &st) == -1); - ASSERT (errno == ENOENT); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "link3", &st) == 0); - ASSERT (S_ISREG (st.st_mode)); - ASSERT (unlink (BASE "link3") == 0); - ASSERT (symlink (BASE "nowhere", BASE "link2") == 0); /* Link onto file. */ - ASSERT (close (creat (BASE "file2", 0600)) == 0); - ASSERT (func (BASE "link2", BASE "file2") == 0); - errno = 0; - ASSERT (lstat (BASE "link2", &st) == -1); - ASSERT (errno == ENOENT); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "file2", &st) == 0); - ASSERT (S_ISLNK (st.st_mode)); - ASSERT (unlink (BASE "file2") == 0); - errno = 0; /* Trailing slash. */ - ASSERT (func (BASE "file/", BASE "link1") == -1); - ASSERT (errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "file", BASE "link1/") == -1); - ASSERT (errno == ENOTDIR || errno == ENOENT); - errno = 0; - ASSERT (func (BASE "link1/", BASE "file") == -1); - ASSERT (errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "link1", BASE "file/") == -1); - ASSERT (errno == ENOTDIR || errno == ENOENT); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "file", &st) == 0); - ASSERT (S_ISREG (st.st_mode)); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "link1", &st) == 0); - ASSERT (S_ISLNK (st.st_mode)); + + { /* File onto link. */ + ASSERT (close (creat (BASE "file2", 0600)) == 0); + /* Files present here: + {BASE}file + {BASE}file2 + {BASE}link1 -> {BASE}file + {BASE}link3 -> {BASE}nowhere + {BASE}dir/ + */ + { + ASSERT (func (BASE "file2", BASE "link3") == 0); + errno = 0; + ASSERT (stat (BASE "file2", &st) == -1); + ASSERT (errno == ENOENT); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "link3", &st) == 0); + ASSERT (S_ISREG (st.st_mode)); + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link3 + {BASE}dir/ + */ + ASSERT (unlink (BASE "link3") == 0); + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}dir/ + */ + { /* Link onto file. */ + ASSERT (symlink (BASE "nowhere", BASE "link2") == 0); + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link2 -> {BASE}nowhere + {BASE}dir/ + */ + ASSERT (close (creat (BASE "file2", 0600)) == 0); + /* Files present here: + {BASE}file + {BASE}file2 + {BASE}link1 -> {BASE}file + {BASE}link2 -> {BASE}nowhere + {BASE}dir/ + */ + { + ASSERT (func (BASE "link2", BASE "file2") == 0); + errno = 0; + ASSERT (lstat (BASE "link2", &st) == -1); + ASSERT (errno == ENOENT); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "file2", &st) == 0); + ASSERT (S_ISLNK (st.st_mode)); + } + /* Files present here: + {BASE}file + {BASE}file2 -> {BASE}nowhere + {BASE}link1 -> {BASE}file + {BASE}dir/ + */ + ASSERT (unlink (BASE "file2") == 0); + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}dir/ + */ + { /* Trailing slash. */ + { + errno = 0; + ASSERT (func (BASE "file/", BASE "link1") == -1); + ASSERT (errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "file", BASE "link1/") == -1); + ASSERT (errno == ENOTDIR || errno == ENOENT); + } + { + errno = 0; + ASSERT (func (BASE "link1/", BASE "file") == -1); + ASSERT (errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "link1", BASE "file/") == -1); + ASSERT (errno == ENOTDIR || errno == ENOENT); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "file", &st) == 0); + ASSERT (S_ISREG (st.st_mode)); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "link1", &st) == 0); + ASSERT (S_ISLNK (st.st_mode)); + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}dir/ + */ /* Mixing symlink and directory. */ - errno = 0; /* Directory onto link. */ - ASSERT (func (BASE "dir", BASE "link1") == -1); - ASSERT (errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "dir/", BASE "link1") == -1); - ASSERT (errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "dir", BASE "link1/") == -1); - ASSERT (errno == ENOTDIR); - errno = 0; /* Link onto directory. */ - ASSERT (func (BASE "link1", BASE "dir") == -1); - ASSERT (errno == EISDIR || errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "link1", BASE "dir/") == -1); - ASSERT (errno == EISDIR || errno == ENOTDIR); - errno = 0; - ASSERT (func (BASE "link1/", BASE "dir") == -1); - ASSERT (errno == ENOTDIR); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "link1", &st) == 0); - ASSERT (S_ISLNK (st.st_mode)); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "dir", &st) == 0); - ASSERT (S_ISDIR (st.st_mode)); + + { /* Directory onto link. */ + { + errno = 0; + ASSERT (func (BASE "dir", BASE "link1") == -1); + ASSERT (errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "dir/", BASE "link1") == -1); + ASSERT (errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "dir", BASE "link1/") == -1); + ASSERT (errno == ENOTDIR); + } + } + { /* Link onto directory. */ + { + errno = 0; + ASSERT (func (BASE "link1", BASE "dir") == -1); + ASSERT (errno == EISDIR || errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "link1", BASE "dir/") == -1); + ASSERT (errno == EISDIR || errno == ENOTDIR); + } + { + errno = 0; + ASSERT (func (BASE "link1/", BASE "dir") == -1); + ASSERT (errno == ENOTDIR); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "link1", &st) == 0); + ASSERT (S_ISLNK (st.st_mode)); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "dir", &st) == 0); + ASSERT (S_ISDIR (st.st_mode)); + } + } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}dir/ + */ /* POSIX requires rename("link-to-dir/","other") to rename "dir" and leave "link-to-dir" dangling, but GNU rejects this. POSIX @@ -376,6 +808,12 @@ test_rename (int (*func) (char const *, char const *), bool print) { int result; ASSERT (symlink (BASE "dir2", BASE "link2") == 0); + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link2 -> {BASE}dir2 + {BASE}dir/ + */ errno = 0; result = func (BASE "dir", BASE "link2/"); if (result == 0) @@ -390,16 +828,24 @@ test_rename (int (*func) (char const *, char const *), bool print) memset (&st, 0, sizeof st); ASSERT (lstat (BASE "link2", &st) == 0); ASSERT (S_ISLNK (st.st_mode)); - ASSERT (func (BASE "link2/", BASE "dir") == 0); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "dir", &st) == 0); - ASSERT (S_ISDIR (st.st_mode)); - errno = 0; - ASSERT (lstat (BASE "dir2", &st) == -1); - ASSERT (errno == ENOENT); - memset (&st, 0, sizeof st); - ASSERT (lstat (BASE "link2", &st) == 0); - ASSERT (S_ISLNK (st.st_mode)); + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link2 -> {BASE}dir2 + {BASE}dir2/ + */ + { + ASSERT (func (BASE "link2/", BASE "dir") == 0); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "dir", &st) == 0); + ASSERT (S_ISDIR (st.st_mode)); + errno = 0; + ASSERT (lstat (BASE "dir2", &st) == -1); + ASSERT (errno == ENOENT); + memset (&st, 0, sizeof st); + ASSERT (lstat (BASE "link2", &st) == 0); + ASSERT (S_ISLNK (st.st_mode)); + } } else { @@ -417,6 +863,12 @@ test_rename (int (*func) (char const *, char const *), bool print) ASSERT (S_ISLNK (st.st_mode)); ASSERT (unlink (BASE "link2") == 0); ASSERT (symlink (BASE "dir", BASE "link2") == 0); + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link2 -> {BASE}dir + {BASE}dir/ + */ errno = 0; /* OpenBSD notices that link2/ and dir are the same. */ result = func (BASE "link2/", BASE "dir"); if (result) /* GNU/Linux rejects attempts to use link2/. */ @@ -435,6 +887,12 @@ test_rename (int (*func) (char const *, char const *), bool print) ASSERT (S_ISLNK (st.st_mode)); } } + /* Files present here: + {BASE}file + {BASE}link1 -> {BASE}file + {BASE}link2 -> {BASE}dir or {BASE}dir2 + {BASE}dir/ + */ /* Clean up. */ ASSERT (unlink (BASE "file") == 0); -- 2.11.0