]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
(make_dir_parents): Make the preceding fix a little
authorJim Meyering <jim@meyering.net>
Mon, 24 Oct 2005 10:22:10 +0000 (10:22 +0000)
committerJim Meyering <jim@meyering.net>
Mon, 24 Oct 2005 10:22:10 +0000 (10:22 +0000)
more robust, e.g., when the final component is created as a non-
directory by another process just before `mkdir -p's final mkdir.

lib/mkdir-p.c

index ac2e28749b7f6cda4f75519e25499dd9ba194014..0206cba9bc2697f22edcc2c84fea385b8f2ea9ea 100644 (file)
@@ -280,7 +280,24 @@ make_dir_parents (char const *arg,
                }
              else
                {
-                 /* The directory already exists.  Do nothing.  */
+                 /* basename_dir exists.
+                    This is highly unlikely, but not impossible in a race.
+                    You can exercise this code by running a very slow
+                    mkdir -p a/nonexistent/c process and e.g., running
+                    touch a/nonexistent/c after a/nonexistent is created
+                    but before mkdir attempts to create `c'.
+
+                    If it's a directory, we're done.
+                    Otherwise, we must fail.  */
+                 struct stat sbuf;
+                 /* The stat may fail for a dangling link.  */
+                 if (stat (basename_dir, &sbuf) != 0
+                     || ! S_ISDIR (sbuf.st_mode))
+                   {
+                     error (0, 0, _("%s exists but is not a directory"),
+                            quote (basename_dir));
+                     retval = false;
+                   }
                }
            }
        }