Module Name:    src
Committed By:   gson
Date:           Mon Jun  8 14:22:01 UTC 2009

Modified Files:
        src/usr.bin/xinstall: xinstall.c

Log Message:
Fix race condition causing "install -d" to randomly fail when multiple
concurrent install processes try to create the same directory.
Modelled after the code handling the "mkdir -p" case in mkdir(1).


To generate a diff of this commit:
cvs rdiff -u -r1.109 -r1.110 src/usr.bin/xinstall/xinstall.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/xinstall/xinstall.c
diff -u src/usr.bin/xinstall/xinstall.c:1.109 src/usr.bin/xinstall/xinstall.c:1.110
--- src/usr.bin/xinstall/xinstall.c:1.109	Fri May  1 20:16:23 2009
+++ src/usr.bin/xinstall/xinstall.c	Mon Jun  8 14:22:01 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: xinstall.c,v 1.109 2009/05/01 20:16:23 apb Exp $	*/
+/*	$NetBSD: xinstall.c,v 1.110 2009/06/08 14:22:01 gson Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993
@@ -46,7 +46,7 @@
 #if 0
 static char sccsid[] = "@(#)xinstall.c	8.1 (Berkeley) 7/21/93";
 #else
-__RCSID("$NetBSD: xinstall.c,v 1.109 2009/05/01 20:16:23 apb Exp $");
+__RCSID("$NetBSD: xinstall.c,v 1.110 2009/06/08 14:22:01 gson Exp $");
 #endif
 #endif /* not lint */
 
@@ -1104,13 +1104,21 @@
                 if (!*p || (p != path && *p  == '/')) {
                         ch = *p;
                         *p = '\0';
-                        if (stat(path, &sb)) {
-                                if (errno != ENOENT || mkdir(path, 0777) < 0) {
+                        if (mkdir(path, 0777) < 0) {
+				/*
+				 * Can't create; path exists or no perms.
+				 * stat() path to determine what's there now.
+				 */
+				int sverrno;
+				sverrno = errno;
+				if (stat(path, &sb) < 0) {
+					/* Not there; use mkdir()s error */
+					errno = sverrno;
 					err(1, "%s: mkdir", path);
                                 }
-                        }
-			else if (!S_ISDIR(sb.st_mode)) {
-				errx(1, "%s exists but is not a directory", path);
+				if (!S_ISDIR(sb.st_mode)) {
+					errx(1, "%s exists but is not a directory", path);
+				}
 			}
                         if (!(*p = ch))
 				break;

Reply via email to