(make_path): Reorder stat-then-mkdir-if-missing
authorJim Meyering <jim@meyering.net>
Tue, 1 Jul 1997 11:50:39 +0000 (11:50 +0000)
committerJim Meyering <jim@meyering.net>
Tue, 1 Jul 1997 11:50:39 +0000 (11:50 +0000)
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.

lib/makepath.c

index 4601294..e6e65f6 100644 (file)
@@ -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);