changeset 960:6f2958d80ce3

(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.
author Jim Meyering <jim@meyering.net>
date Tue, 01 Jul 1997 11:50:39 +0000
parents 6c940cbf4166
children 6959c7741ed2
files lib/makepath.c
diffstat 1 files changed, 29 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/lib/makepath.c
+++ b/lib/makepath.c
@@ -214,48 +214,50 @@
 	    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);
-
-		  if (owner != (uid_t) -1 && group != (gid_t) -1
-		      && chown (basename_dir, owner, group)
-#if defined(AFS) && defined (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;
-		    }
+		  /* DIRPATH already exists and is a directory. */
 		}
 	    }
-	  else if (!S_ISDIR (stats.st_mode))
+
+	  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
+#endif
+	      )
 	    {
-	      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);