diff options
author | Jim Meyering <jim@meyering.net> | 2005-10-24 13:35:59 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2005-10-24 13:35:59 +0000 |
commit | e8871a9516f334a7822f3f3f9d9f9bcb92c59e9d (patch) | |
tree | 448dd4096f46f8df15117f47aff9420be99ecd96 /lib/mkdir-p.c | |
parent | 30bf08a3da239bc110e20e61dacd0afa4dc18958 (diff) | |
download | coreutils-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.c | 46 |
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; } } } |