autoupdate
[gnulib.git] / tests / test-rename.h
index 9753052..7e024e0 100644 (file)
@@ -1,5 +1,5 @@
 /* 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)
 {
@@ -226,9 +274,7 @@ 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
@@ -263,9 +309,7 @@ test_rename (int (*func) (char const *, char const *), bool print)
        */
       {
         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:
@@ -295,12 +339,12 @@ test_rename (int (*func) (char const *, char const *), bool print)
         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:
@@ -322,12 +366,12 @@ test_rename (int (*func) (char const *, char const *), bool print)
         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:
@@ -744,6 +788,7 @@ test_rename (int (*func) (char const *, char const *), bool print)
       ASSERT (lstat (BASE "link1", &st) == 0);
       ASSERT (S_ISLNK (st.st_mode));
     }
+  }
   /* Files present here:
        {BASE}file
        {BASE}link1 -> {BASE}file
@@ -874,7 +919,7 @@ test_rename (int (*func) (char const *, char const *), bool print)
         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);