summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1997-07-01 11:50:39 +0000
committerJim Meyering <jim@meyering.net>1997-07-01 11:50:39 +0000
commit2499628bff30fb822862f9ae406bb21b63d5c2c9 (patch)
tree7d5cd0c105badb02b4891cbe600004ef54029aac /lib
parentb5e0f033a6d0a9e4af4b7bb67ebd00f076c2a529 (diff)
downloadcoreutils-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.c54
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);