/* Test of rename() function.
- Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2009-2013 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)
{
}
{ /* Full onto empty. */
ASSERT (func (BASE "dir", BASE "dir2") == 0);
- errno = 0;
- ASSERT (stat (BASE "dir", &st) == -1);
- ASSERT (errno == ENOENT);
+ assert_nonexistent (BASE "dir");
ASSERT (stat (BASE "dir2/file", &st) == 0);
/* Files present here:
{BASE}file
*/
{
ASSERT (func (BASE "dir", BASE "dir2/") == 0);
- errno = 0;
- ASSERT (stat (BASE "dir", &st) == -1);
- ASSERT (errno == ENOENT);
+ assert_nonexistent (BASE "dir");
ASSERT (stat (BASE "dir2/file", &st) == 0);
}
/* Files present here:
errno = 0;
ASSERT (func (BASE "dir2", BASE "dir/.") == -1);
ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR
- || errno == ENOTEMPTY);
+ || errno == ENOTEMPTY || errno == EEXIST);
}
{
errno = 0;
ASSERT (func (BASE "dir2/.", BASE "dir") == -1);
- ASSERT (errno == EINVAL || errno == EBUSY);
+ ASSERT (errno == EINVAL || errno == EBUSY || errno == EEXIST);
}
ASSERT (rmdir (BASE "dir") == 0);
/* Files present here:
errno = 0;
ASSERT (func (BASE "dir2", BASE "dir/.//") == -1);
ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR
- || errno == ENOTEMPTY);
+ || errno == ENOTEMPTY || errno == EEXIST);
}
{
errno = 0;
ASSERT (func (BASE "dir2/.//", BASE "dir") == -1);
- ASSERT (errno == EINVAL || errno == EBUSY);
+ ASSERT (errno == EINVAL || errno == EBUSY || errno == EEXIST);
}
ASSERT (rmdir (BASE "dir2") == 0);
/* Files present here:
ASSERT (lstat (BASE "link1", &st) == 0);
ASSERT (S_ISLNK (st.st_mode));
}
+ }
/* Files present here:
{BASE}file
{BASE}link1 -> {BASE}file
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);