OSDN Git Service

Adjust mkdir_p to do stat() before trying mkdir(). Avoids problems on
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 28 Jan 2005 00:34:32 +0000 (00:34 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 28 Jan 2005 00:34:32 +0000 (00:34 +0000)
Solaris and should be a little faster anyway, since in most scenarios
all but perhaps the last path component will already exist.

src/bin/initdb/initdb.c

index 2d3958b..9077d84 100644 (file)
@@ -39,7 +39,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  * Portions taken from FreeBSD.
  *
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.73 2005/01/08 22:51:12 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.74 2005/01/28 00:34:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -476,6 +476,9 @@ popen_check(const char *command, const char *mode)
  * this tries to build all the elements of a path to a directory a la mkdir -p
  * we assume the path is in canonical form, i.e. uses / as the separator
  * we also assume it isn't null.
+ *
+ * note that on failure, the path arg has been modified to show the particular
+ * directory level we had problems with.
  */
 static int
 mkdir_p(char *path, mode_t omode)
@@ -544,31 +547,25 @@ mkdir_p(char *path, mode_t omode)
                }
                if (last)
                        (void) umask(oumask);
-               if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
+
+               /* check for pre-existing directory; ok if it's a parent */
+               if (stat(path, &sb) == 0)
                {
-                       if (errno == EEXIST || errno == EISDIR)
-                       {
-                               if (stat(path, &sb) < 0)
-                               {
-                                       retval = 1;
-                                       break;
-                               }
-                               else if (!S_ISDIR(sb.st_mode))
-                               {
-                                       if (last)
-                                               errno = EEXIST;
-                                       else
-                                               errno = ENOTDIR;
-                                       retval = 1;
-                                       break;
-                               }
-                       }
-                       else
+                       if (!S_ISDIR(sb.st_mode))
                        {
+                               if (last)
+                                       errno = EEXIST;
+                               else
+                                       errno = ENOTDIR;
                                retval = 1;
                                break;
                        }
                }
+               else if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
+               {
+                       retval = 1;
+                       break;
+               }
                if (!last)
                        *p = '/';
        }