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).
This commit is contained in:
parent
e1a778e452
commit
57a8678315
@ -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
|
* Copyright (c) 1987, 1993
|
||||||
@ -46,7 +46,7 @@ __COPYRIGHT("@(#) Copyright (c) 1987, 1993\
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)xinstall.c 8.1 (Berkeley) 7/21/93";
|
static char sccsid[] = "@(#)xinstall.c 8.1 (Berkeley) 7/21/93";
|
||||||
#else
|
#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
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@ -1104,14 +1104,22 @@ install_dir(char *path, u_int flags)
|
|||||||
if (!*p || (p != path && *p == '/')) {
|
if (!*p || (p != path && *p == '/')) {
|
||||||
ch = *p;
|
ch = *p;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
if (stat(path, &sb)) {
|
if (mkdir(path, 0777) < 0) {
|
||||||
if (errno != ENOENT || 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);
|
err(1, "%s: mkdir", path);
|
||||||
}
|
}
|
||||||
}
|
if (!S_ISDIR(sb.st_mode)) {
|
||||||
else if (!S_ISDIR(sb.st_mode)) {
|
|
||||||
errx(1, "%s exists but is not a directory", path);
|
errx(1, "%s exists but is not a directory", path);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!(*p = ch))
|
if (!(*p = ch))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user