Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
patch 8.0.1708: mkdir with 'p' flag fails on existing directory
Problem:    Mkdir with 'p' flag fails on existing directory, which is
            different from the mkdir shell command.
Solution:   Don't fail if the directory already exists. (James McCoy,
            closes #2775)
  • Loading branch information
brammool committed Apr 14, 2018
1 parent 98da6ec commit 78a16b0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 12 deletions.
2 changes: 2 additions & 0 deletions runtime/doc/eval.txt
Expand Up @@ -6138,6 +6138,8 @@ mkdir({name} [, {path} [, {prot}]])
Example: >
:call mkdir($HOME . "/tmp/foo/bar", "p", 0700)
< This function is not available in the |sandbox|.
There is no error if the directory already exists and the "p"
flag is passed (since patch 8.0.1708).
Not available on all systems. To check use: >
:if exists("*mkdir")
<
Expand Down
34 changes: 22 additions & 12 deletions src/evalfunc.c
Expand Up @@ -8057,22 +8057,32 @@ f_mkdir(typval_T *argvars, typval_T *rettv)

dir = get_tv_string_buf(&argvars[0], buf);
if (*dir == NUL)
rettv->vval.v_number = FAIL;
else
{
if (*gettail(dir) == NUL)
/* remove trailing slashes */
*gettail_sep(dir) = NUL;
return;

if (argvars[1].v_type != VAR_UNKNOWN)
if (*gettail(dir) == NUL)
/* remove trailing slashes */
*gettail_sep(dir) = NUL;

if (argvars[1].v_type != VAR_UNKNOWN)
{
if (argvars[2].v_type != VAR_UNKNOWN)
{
if (argvars[2].v_type != VAR_UNKNOWN)
prot = (int)get_tv_number_chk(&argvars[2], NULL);
if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0)
mkdir_recurse(dir, prot);
prot = (int)get_tv_number_chk(&argvars[2], NULL);
if (prot == -1)
return;
}
if (STRCMP(get_tv_string(&argvars[1]), "p") == 0)
{
if (mch_isdir(dir))
{
/* With the "p" flag it's OK if the dir already exists. */
rettv->vval.v_number = OK;
return;
}
mkdir_recurse(dir, prot);
}
rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot);
}
rettv->vval.v_number = vim_mkdir_emsg(dir, prot);
}
#endif

Expand Down
17 changes: 17 additions & 0 deletions src/testdir/test_eval_stuff.vim
Expand Up @@ -25,3 +25,20 @@ func Test_nocatch_restore_silent_emsg()
let c5 = nr2char(screenchar(&lines, 5))
call assert_equal('wrong', c1 . c2 . c3 . c4 . c5)
endfunc

func Test_mkdir_p()
call mkdir('Xmkdir/nested', 'p')
call assert_true(isdirectory('Xmkdir/nested'))
try
" Trying to make existing directories doesn't error
call mkdir('Xmkdir', 'p')
call mkdir('Xmkdir/nested', 'p')
catch /E739:/
call assert_report('mkdir(..., "p") failed for an existing directory')
endtry
" 'p' doesn't suppress real errors
call writefile([], 'Xfile')
call assert_fails('call mkdir("Xfile", "p")', 'E739')
call delete('Xfile')
call delete('Xmkdir', 'rf')
endfunc
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -762,6 +762,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1708,
/**/
1707,
/**/
Expand Down

0 comments on commit 78a16b0

Please sign in to comment.