/* Test of rename() function.
- Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2009-2011 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
appropriate headers are already included. If PRINT, warn before
skipping symlink tests with status 77. */
+/* Tests whether a file, given by a file name without slashes, exists in
+ the current directory, by scanning the directory entries. */
+static bool
+dentry_exists (const char *filename)
+{
+ bool exists = false;
+ DIR *dir = opendir (".");
+
+ ASSERT (dir != NULL);
+ for (;;)
+ {
+ struct dirent *d = readdir (dir);
+ if (d == NULL)
+ break;
+ if (strcmp (d->d_name, filename) == 0)
+ {
+ exists = true;
+ break;
+ }
+ }
+ ASSERT (closedir (dir) == 0);
+ return exists;
+}
+
+/* Asserts that a specific file, given by a file name without slashes, does
+ not exist in the current directory. */
+static void
+assert_nonexistent (const char *filename)
+{
+ struct stat st;
+
+ /* The usual way to test the presence of a file is via stat() or lstat(). */
+ errno = 0;
+ if (stat (filename, &st) == -1)
+ ASSERT (errno == ENOENT);
+ else
+ {
+ /* But after renaming a directory over an empty directory on an NFS-
+ mounted file system, on Linux 2.6.18, for a period of 30 seconds the
+ old directory name is "present" according to stat() but "nonexistent"
+ according to dentry_exists(). */
+ ASSERT (!dentry_exists (filename));
+ /* Remove the old directory name, so that subsequent mkdir calls
+ succeed. */
+ (void) rmdir (filename);
+ }
+}
+
static int
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);
+ assert_nonexistent (BASE "dir");
+ 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);
+ assert_nonexistent (BASE "dir");
+ 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 || errno == EEXIST);
+ }
+ 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 || errno == EEXIST);
+ }
+ 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
}
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)
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
{
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)
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
{
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/. */
{
ASSERT (result == -1);
- ASSERT (errno == ENOTDIR);
+ ASSERT (errno == ENOTDIR || errno == EISDIR);
}
memset (&st, 0, sizeof st);
ASSERT (lstat (BASE "dir", &st) == 0);
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);