mkdir - Fix MP race in mkdir -p
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 30 Nov 2011 17:52:08 +0000 (09:52 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 30 Nov 2011 17:52:08 +0000 (09:52 -0800)
* mkdir -p can race other mkdir -p commands

* Do the same fix that we did for xinstall... if the mkdir() fails after
  the stat() check, stat() again to see if the directory creation raced.

bin/mkdir/mkdir.c

index 0584d4d..c3f2763 100644 (file)
@@ -49,6 +49,7 @@
 #include <unistd.h>
 
 static int     build(char *, mode_t);
+static int     mkdir_race(const char *path, int nmode);
 static void    usage(void);
 
 int vflag;
@@ -172,7 +173,7 @@ build(char *path, mode_t omode)
                        umask(oumask);
                if (stat(path, &sb)) {
                        if (errno != ENOENT ||
-                           mkdir(path, last ? omode : 
+                           mkdir_race(path, last ? omode :
                                  S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
                                warn("%s", path);
                                retval = 1;
@@ -197,6 +198,21 @@ build(char *path, mode_t omode)
        return (retval);
 }
 
+int
+mkdir_race(const char *path, int nmode)
+{
+       int res;
+       struct stat sb;
+
+       res = mkdir(path, nmode);
+       if (res < 0 && errno == EEXIST) {
+              if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode))
+                      return(0);
+              res = mkdir(path, nmode);
+       }
+       return (res);
+}
+
 static void
 usage(void)
 {