From 929821126f0822884ef5d75c8f737e1b734374a2 Mon Sep 17 00:00:00 2001 From: christos Date: Tue, 13 Sep 2005 15:50:17 +0000 Subject: [PATCH] when creating directories, check if the failure occured because someone else created the directory before we did to avoid races. From chuq. --- bin/pax/file_subs.c | 16 +++++++++++++--- bin/pax/options.c | 26 ++++++++++++++------------ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c index db6901d42bdf..a65bd3ae30f4 100644 --- a/bin/pax/file_subs.c +++ b/bin/pax/file_subs.c @@ -1,4 +1,4 @@ -/* $NetBSD: file_subs.c,v 1.53 2005/04/24 01:24:57 christos Exp $ */ +/* $NetBSD: file_subs.c,v 1.54 2005/09/13 15:50:17 christos Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: file_subs.c,v 1.53 2005/04/24 01:24:57 christos Exp $"); +__RCSID("$NetBSD: file_subs.c,v 1.54 2005/09/13 15:50:17 christos Exp $"); #endif #endif /* not lint */ @@ -465,7 +465,17 @@ node_creat(ARCHD *arcn) } } res = mkdir(nm, file_mode); - + if (res == -1 && errno == EEXIST) { + /* + * Something's in the way. + * If it's a directory, say we're done. + */ + if (lstat(nm, &sb) == 0 && + S_ISDIR(sb.st_mode)) { + res = 0; + break; + } + } badlink: if (ign) res = 0; diff --git a/bin/pax/options.c b/bin/pax/options.c index 008de8b8f5e9..ff5dcad31166 100644 --- a/bin/pax/options.c +++ b/bin/pax/options.c @@ -1,4 +1,4 @@ -/* $NetBSD: options.c,v 1.89 2005/06/29 02:21:27 christos Exp $ */ +/* $NetBSD: options.c,v 1.90 2005/09/13 15:50:17 christos Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; #else -__RCSID("$NetBSD: options.c,v 1.89 2005/06/29 02:21:27 christos Exp $"); +__RCSID("$NetBSD: options.c,v 1.90 2005/09/13 15:50:17 christos Exp $"); #endif #endif /* not lint */ @@ -690,7 +690,7 @@ pax_options(int argc, char **argv) --argc; dirptr = argv[argc]; if (mkpath(dirptr) < 0) - pax_usage(); + exit(1); /* FALLTHROUGH */ case ARCHIVE: case APPND: @@ -1324,7 +1324,7 @@ mkpath(path) { struct stat sb; char *slash; - int done = 0; + int done = 0, sverrno; slash = path; @@ -1335,21 +1335,23 @@ mkpath(path) done = (*slash == '\0'); *slash = '\0'; - if (stat(path, &sb)) { - if (errno != ENOENT || mkdir(path, 0777)) { - tty_warn(1, "%s", path); - return (-1); + if (mkdir(path, 0777) == -1) { + /* Check if it was created it for us in the meantime */ + sverrno = errno; + + if (lstat(path, &sb) == -1 || !S_ISDIR(sb.st_mode)) { + /* Can't create or or not a directory */ + syswarn(1, sverrno, + "Cannot create directory `%s'", path); + return -1; } - } else if (!S_ISDIR(sb.st_mode)) { - syswarn(1, ENOTDIR, "%s", path); - return (-1); } if (!done) *slash = '/'; } - return (0); + return 0; }