summaryrefslogtreecommitdiff
path: root/lib/mkdir-p.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2005-10-24 13:35:59 +0000
committerJim Meyering <jim@meyering.net>2005-10-24 13:35:59 +0000
commite8871a9516f334a7822f3f3f9d9f9bcb92c59e9d (patch)
tree448dd4096f46f8df15117f47aff9420be99ecd96 /lib/mkdir-p.c
parent30bf08a3da239bc110e20e61dacd0afa4dc18958 (diff)
downloadcoreutils-e8871a9516f334a7822f3f3f9d9f9bcb92c59e9d.tar.xz
(make_dir_parents): Like the code above it, don't rely
on mkdir failing with a particular errno value (EEXIST). Based on a patch by Dmitry V. Levin.
Diffstat (limited to 'lib/mkdir-p.c')
-rw-r--r--lib/mkdir-p.c46
1 files changed, 15 insertions, 31 deletions
diff --git a/lib/mkdir-p.c b/lib/mkdir-p.c
index 0206cba9b..e970e118d 100644
--- a/lib/mkdir-p.c
+++ b/lib/mkdir-p.c
@@ -264,41 +264,25 @@ make_dir_parents (char const *arg,
Create the final component of the file name. */
if (retval)
{
- bool just_created = (mkdir (basename_dir, mode) == 0);
- if (just_created)
+ bool dir_known_to_exist = (mkdir (basename_dir, mode) == 0);
+ int mkdir_errno = errno;
+ struct stat sbuf;
+
+ if ( ! dir_known_to_exist)
+ dir_known_to_exist = (stat (basename_dir, &sbuf) == 0
+ && S_ISDIR (sbuf.st_mode));
+
+ if ( ! dir_known_to_exist)
{
- if (verbose_fmt_string)
- error (0, 0, verbose_fmt_string, quote (dir));
- fixup_permissions_dir = basename_dir;
+ error (0, mkdir_errno,
+ _("cannot create directory %s"), quote (dir));
+ retval = false;
}
else
{
- if (errno != EEXIST)
- {
- error (0, errno, _("cannot create directory %s"), quote (dir));
- retval = false;
- }
- else
- {
- /* 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;
- }
- }
+ if (verbose_fmt_string)
+ error (0, 0, verbose_fmt_string, quote (dir));
+ fixup_permissions_dir = basename_dir;
}
}
}