Another missing mkdir() race pointed out by chuq. Factor out the mkdir code.
This commit is contained in:
parent
c4b850a8a6
commit
b60b306ef2
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ar_subs.c,v 1.42 2005/05/22 17:41:50 christos Exp $ */
|
||||
/* $NetBSD: ar_subs.c,v 1.43 2005/09/16 16:48:18 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
@ -42,7 +42,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ar_subs.c,v 1.42 2005/05/22 17:41:50 christos Exp $");
|
||||
__RCSID("$NetBSD: ar_subs.c,v 1.43 2005/09/16 16:48:18 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -124,6 +124,29 @@ fdochroot(int fcwd)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* mkdir(), but if we failed, check if someone else made it for us
|
||||
* already and don't error out.
|
||||
*/
|
||||
int
|
||||
domkdir(const char *fname, mode_t mode)
|
||||
{
|
||||
int error;
|
||||
struct stat sb;
|
||||
|
||||
if ((error = mkdir(fname, mode)) != -1 || errno != EEXIST)
|
||||
return error;
|
||||
|
||||
error = errno;
|
||||
|
||||
if (stat(fname, &sb) == 0 && S_ISDIR(sb.st_mode))
|
||||
return 0;
|
||||
|
||||
errno = error;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
path_check(ARCHD *arcn, int level)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: extern.h,v 1.48 2005/04/24 01:45:04 christos Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.49 2005/09/16 16:48:18 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
@ -85,6 +85,7 @@ extern ARCHD archd;
|
||||
int updatepath(void);
|
||||
int dochdir(const char *);
|
||||
int fdochdir(int);
|
||||
int domkdir(const char *, mode_t);
|
||||
void list(void);
|
||||
void extract(void);
|
||||
void append(void);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: file_subs.c,v 1.55 2005/09/13 20:09:55 christos Exp $ */
|
||||
/* $NetBSD: file_subs.c,v 1.56 2005/09/16 16:48:18 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.55 2005/09/13 20:09:55 christos Exp $");
|
||||
__RCSID("$NetBSD: file_subs.c,v 1.56 2005/09/16 16:48:18 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -464,18 +464,7 @@ node_creat(ARCHD *arcn)
|
||||
nm = target;
|
||||
}
|
||||
}
|
||||
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 (stat(nm, &sb) == 0 &&
|
||||
S_ISDIR(sb.st_mode)) {
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
res = domkdir(nm, file_mode);
|
||||
badlink:
|
||||
if (ign)
|
||||
res = 0;
|
||||
@ -730,7 +719,7 @@ chk_path(char *name, uid_t st_uid, gid_t st_gid)
|
||||
* the path fails at this point, see if we can create the
|
||||
* needed directory and continue on
|
||||
*/
|
||||
if (mkdir(name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
|
||||
if (domkdir(name, S_IRWXU | S_IRWXG | S_IRWXO) == -1) {
|
||||
*spt = '/';
|
||||
retval = -1;
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: options.c,v 1.91 2005/09/13 20:09:55 christos Exp $ */
|
||||
/* $NetBSD: options.c,v 1.92 2005/09/16 16:48:18 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.91 2005/09/13 20:09:55 christos Exp $");
|
||||
__RCSID("$NetBSD: options.c,v 1.92 2005/09/16 16:48:18 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -1322,9 +1322,8 @@ int
|
||||
mkpath(path)
|
||||
char *path;
|
||||
{
|
||||
struct stat sb;
|
||||
char *slash;
|
||||
int done = 0, sverrno;
|
||||
int done = 0;
|
||||
|
||||
slash = path;
|
||||
|
||||
@ -1335,20 +1334,8 @@ mkpath(path)
|
||||
done = (*slash == '\0');
|
||||
*slash = '\0';
|
||||
|
||||
if (stat(path, &sb) == -1) {
|
||||
if ((sverrno = errno) != ENOENT)
|
||||
goto out;
|
||||
if (mkdir(path, 0777) == -1) {
|
||||
sverrno = errno;
|
||||
/* Check again, to avoid races */
|
||||
if (stat(path, &sb) == -1
|
||||
|| !S_ISDIR(sb.st_mode))
|
||||
goto out;
|
||||
}
|
||||
} else if (!S_ISDIR(sb.st_mode)) {
|
||||
sverrno = ENOTDIR;
|
||||
if (domkdir(path, 0777) == -1)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!done)
|
||||
*slash = '/';
|
||||
@ -1357,7 +1344,7 @@ mkpath(path)
|
||||
return 0;
|
||||
out:
|
||||
/* Can't create or or not a directory */
|
||||
syswarn(1, sverrno, "Cannot create directory `%s'", path);
|
||||
syswarn(1, errno, "Cannot create directory `%s'", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user