1
0
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:
Roman Perepelitsa 2020-10-23 11:42:30 +02:00
parent da534770fd
commit ead29c2a36
2 changed files with 24 additions and 9 deletions

View File

@ -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

View File

@ -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;
}