diff options
author | Jim Meyering <jim@meyering.net> | 1997-07-01 11:50:39 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 1997-07-01 11:50:39 +0000 |
commit | 2499628bff30fb822862f9ae406bb21b63d5c2c9 (patch) | |
tree | 7d5cd0c105badb02b4891cbe600004ef54029aac /lib | |
parent | b5e0f033a6d0a9e4af4b7bb67ebd00f076c2a529 (diff) | |
download | coreutils-2499628bff30fb822862f9ae406bb21b63d5c2c9.tar.xz |
(make_path): Reorder stat-then-mkdir-if-missing
calls so that mkdir is called first. Before make_path would first
`stat' a directory, then call mkdir if it didn't exist. But if
some other process created the directory between the stat & mkdir,
the mkdir would fail with EEXIST. Diagnosis and suggestion from
Greg McGary.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/makepath.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/lib/makepath.c b/lib/makepath.c index 460129477..e6e65f632 100644 --- a/lib/makepath.c +++ b/lib/makepath.c @@ -214,48 +214,50 @@ make_path (argpath, mode, parent_mode, owner, group, preserve_existing, basename_dir = dirpath; *slash = '\0'; - if (stat (basename_dir, &stats)) + if (mkdir (basename_dir, tmp_mode)) { - if (mkdir (basename_dir, tmp_mode)) + if (stat (basename_dir, &stats)) { error (0, errno, "cannot create directory `%s'", dirpath); CLEANUP; return 1; } + else if (!S_ISDIR (stats.st_mode)) + { + error (0, 0, "`%s' exists but is not a directory", dirpath); + CLEANUP; + return 1; + } else { - if (verbose_fmt_string != NULL) - error (0, 0, verbose_fmt_string, dirpath); + /* DIRPATH already exists and is a directory. */ + } + } - if (owner != (uid_t) -1 && group != (gid_t) -1 - && chown (basename_dir, owner, group) + if (verbose_fmt_string != NULL) + error (0, 0, verbose_fmt_string, dirpath); + + if (owner != (uid_t) -1 && group != (gid_t) -1 + && chown (basename_dir, owner, group) #if defined(AFS) && defined (EPERM) - && errno != EPERM + && errno != EPERM #endif - ) - { - error (0, errno, "%s", dirpath); - CLEANUP; - return 1; - } - - if (re_protect) - { - struct ptr_list *new = (struct ptr_list *) - alloca (sizeof (struct ptr_list)); - new->dirname_end = slash; - new->next = leading_dirs; - leading_dirs = new; - } - } - } - else if (!S_ISDIR (stats.st_mode)) + ) { - error (0, 0, "`%s' exists but is not a directory", dirpath); + error (0, errno, "%s", dirpath); CLEANUP; return 1; } + if (re_protect) + { + struct ptr_list *new = (struct ptr_list *) + alloca (sizeof (struct ptr_list)); + new->dirname_end = slash; + new->next = leading_dirs; + leading_dirs = new; + } + if (saved_cwd && chdir (basename_dir) < 0) { error (0, errno, "cannot chdir to directory, %s", dirpath); |