]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.0.1708: mkdir with 'p' flag fails on existing directory v8.0.1708
authorBram Moolenaar <Bram@vim.org>
Sat, 14 Apr 2018 11:51:55 +0000 (13:51 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 14 Apr 2018 11:51:55 +0000 (13:51 +0200)
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)

runtime/doc/eval.txt
src/evalfunc.c
src/testdir/test_eval_stuff.vim
src/version.c

index b0170b847b7c511f3d2cda82fde47e24a0306056..1868f4ee73e95614fc5d1d721bafe692f6686e1f 100644 (file)
@@ -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")
 <
index 65279a52f8b4e54ae08061c43b1bbba0bb13d10e..4b09951852b0aa740f979d23d754379ccdbc5b82 100644 (file)
@@ -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
 
index 12222303d363104c2d74b493b2a4f3c1d4d5e7f6..41ba1374d8e054578dda7affb2b0119cf9bfd5dd 100644 (file)
@@ -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
index 5facbc58114e1ec5025ae95fa4f55c42e38ddda4..6bebac291360d5eab7a52b10b273f9e47e91520b 100644 (file)
@@ -762,6 +762,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1708,
 /**/
     1707,
 /**/