diff options
author | zarzycki <zarzycki@FreeBSD.org> | 2002-02-05 21:55:12 +0000 |
---|---|---|
committer | zarzycki <zarzycki@FreeBSD.org> | 2002-02-05 21:55:12 +0000 |
commit | 98e34f92cb576f8096793659805327afe5ceaef3 (patch) | |
tree | 08e4176a4882aa13dbf684da0b3c50dc93730861 /bin/mkdir | |
parent | 39b59a2a202dece886ca3761c3237e00c694b3e2 (diff) | |
download | FreeBSD-src-98e34f92cb576f8096793659805327afe5ceaef3.zip FreeBSD-src-98e34f92cb576f8096793659805327afe5ceaef3.tar.gz |
Fix the race between the stat() and the mkdir().
Reviewed by: jkh
Diffstat (limited to 'bin/mkdir')
-rw-r--r-- | bin/mkdir/mkdir.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/bin/mkdir/mkdir.c b/bin/mkdir/mkdir.c index 417f7a3..bc06ff9 100644 --- a/bin/mkdir/mkdir.c +++ b/bin/mkdir/mkdir.c @@ -173,25 +173,28 @@ build(char *path, mode_t omode) } if (last) (void)umask(oumask); - if (stat(path, &sb)) { - if (errno != ENOENT || - mkdir(path, last ? omode : - S_IRWXU | S_IRWXG | S_IRWXO) < 0) { + if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) { + if (errno == EEXIST) { + if (stat(path, &sb) < 0) { + warn("%s", path); + retval = 1; + break; + } else if (!S_ISDIR(sb.st_mode)) { + if (last) + errno = EEXIST; + else + errno = ENOTDIR; + warn("%s", path); + retval = 1; + break; + } + } else { warn("%s", path); retval = 1; break; - } else if (vflag) - printf("%s\n", path); - } - else if ((sb.st_mode & S_IFMT) != S_IFDIR) { - if (last) - errno = EEXIST; - else - errno = ENOTDIR; - warn("%s", path); - retval = 1; - break; - } + } + } else if (vflag) + printf("%s\n", path); if (!last) *p = '/'; } |