diff options
author | mjg <mjg@FreeBSD.org> | 2014-09-23 11:41:09 +0000 |
---|---|---|
committer | mjg <mjg@FreeBSD.org> | 2014-09-23 11:41:09 +0000 |
commit | 6ca5e81a1632f8d4048ee0028c9081129e51d3bc (patch) | |
tree | b2298075cdd7fd822b4b635f873133e891dd8864 /usr.bin | |
parent | 49648b28cfa88cd995a1ba9a8d50eb4af92c08a7 (diff) | |
download | FreeBSD-src-6ca5e81a1632f8d4048ee0028c9081129e51d3bc.zip FreeBSD-src-6ca5e81a1632f8d4048ee0028c9081129e51d3bc.tar.gz |
install: re-check failed mkdir for EEXIST
Since the code stats and mkdirs in 2 separate steps, it is possible that
the directory will be created in the meantime by something else (e.g.
concurrent install).[1]
While here alter the code to properly report stat failure, previously it
would always claim it was mkdir which failed.
Noted by: royger [1]
MFC after: 1 week
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/xinstall/xinstall.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index f40cdc5..b59db70 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -1263,13 +1263,18 @@ install_dir(char *path) if (!*p || (p != path && *p == '/')) { ch = *p; *p = '\0'; - if (stat(path, &sb)) { - if (errno != ENOENT || mkdir(path, 0755) < 0) { +again: + if (stat(path, &sb) < 0) { + if (errno != ENOENT) + err(EX_OSERR, "stat %s", path); + if (mkdir(path, 0755) < 0) { + if (errno == EEXIST) + goto again; err(EX_OSERR, "mkdir %s", path); - /* NOTREACHED */ - } else if (verbose) + } + if (verbose) (void)printf("install: mkdir %s\n", - path); + path); } else if (!S_ISDIR(sb.st_mode)) errx(EX_OSERR, "%s exists but is not a directory", path); if (!(*p = ch)) |