mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-09-22 03:40:47 +02:00
Fix a race condition in zf_mkdir -p
If ~/foo does not exist and `zf_mkdir -p zf_mkdir -p` is executed concurrently in multiple shells, it was possible prior to this patch for the command to fail with EEXIST.
This commit is contained in:
parent
da534770fd
commit
ead29c2a36
@ -1,3 +1,8 @@
|
||||
2020-10-18 Roman Perepelitsa <roman.perepelitsa@gmail.com>
|
||||
|
||||
* 47476: Src/Modules/files.c: Fix a race condition in zf_mkdir -p
|
||||
(based on the patch by Matthew Martin in workers/47436)
|
||||
|
||||
2020-10-18 Axel Beckert <abe@deuxchevaux.org>
|
||||
|
||||
* 47468: Doc/Zsh/contrib.yo: Fix typo
|
||||
|
@ -122,19 +122,29 @@ domkdir(char *nam, char *path, mode_t mode, int p)
|
||||
{
|
||||
int err;
|
||||
mode_t oumask;
|
||||
struct stat st;
|
||||
int n = 8;
|
||||
char const *rpath = unmeta(path);
|
||||
|
||||
if(p) {
|
||||
struct stat st;
|
||||
|
||||
if(!stat(rpath, &st) && S_ISDIR(st.st_mode))
|
||||
while(n-- > 0) {
|
||||
oumask = umask(0);
|
||||
err = mkdir(rpath, mode) ? errno : 0;
|
||||
umask(oumask);
|
||||
if (!err)
|
||||
return 0;
|
||||
if(!p || err != EEXIST)
|
||||
break;
|
||||
if(stat(rpath, &st)) {
|
||||
if(errno == ENOENT)
|
||||
continue;
|
||||
err = errno;
|
||||
break;
|
||||
}
|
||||
if(S_ISDIR(st.st_mode))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
oumask = umask(0);
|
||||
err = mkdir(rpath, mode) ? errno : 0;
|
||||
umask(oumask);
|
||||
if(!err)
|
||||
return 0;
|
||||
|
||||
zwarnnam(nam, "cannot make directory `%s': %e", path, err);
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user