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;