From b8cedd257ad21e739caaaf77cb5d26514686d942 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 24 Oct 2005 10:22:10 +0000 Subject: [PATCH] (make_dir_parents): Make the preceding fix a little 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 | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/mkdir-p.c b/lib/mkdir-p.c index ac2e28749b..0206cba9bc 100644 --- a/lib/mkdir-p.c +++ b/lib/mkdir-p.c @@ -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; + } } } } -- 2.47.3