diff options
author | Jurica Bradaric <jbradaric@gmail.com> | 2016-02-28 12:44:59 +0100 |
---|---|---|
committer | Jurica Bradaric <jbradaric@gmail.com> | 2016-04-20 08:25:51 +0200 |
commit | 88a735166b7ee1eadaf6d46be11804dc0e1a251a (patch) | |
tree | 2b39c525bb9120f6cc192106f0f93d7b4ca9016a | |
parent | 50a7517a6deb7d8eaa02bf718e273b7058066d89 (diff) | |
download | rneovim-88a735166b7ee1eadaf6d46be11804dc0e1a251a.tar.gz rneovim-88a735166b7ee1eadaf6d46be11804dc0e1a251a.tar.bz2 rneovim-88a735166b7ee1eadaf6d46be11804dc0e1a251a.zip |
vim-patch:7.4.1114
Problem: delete() does not work well with symbolic links.
Solution: Recognize symbolik links.
https://github.com/vim/vim/commit/43a34f9f74fdce462fa250baab620264c28b6165
-rw-r--r-- | runtime/doc/eval.txt | 7 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 17 | ||||
-rw-r--r-- | src/nvim/tempfile.c | 2 | ||||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | test/functional/legacy/delete_spec.lua | 57 |
5 files changed, 80 insertions, 5 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 9437491623..fea9423df2 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2772,13 +2772,14 @@ deepcopy({expr}[, {noref}]) *deepcopy()* *E698* delete({fname} [, {flags}]) *delete()* Without {flags} or with {flags} empty: Deletes the file by the - name {fname}. + name {fname}. This also works when {fname} is a symbolic link. + A symbolic link itself is deleted, not what it points to. When {flags} is "d": Deletes the directory by the name - {fname}. This fails when {fname} is not empty. + {fname}. This fails when directory {fname} is not empty. When {flags} is "rf": Deletes the directory by the name - {fname} and everything in it, recursively. Be careful! + {fname} and everything in it, recursively. BE CAREFUL! The result is a Number, which is 0 if the delete operation was successful and -1 when the deletion failed or partly failed. diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 34d8fde4f1..bc2d37764d 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -59,6 +59,23 @@ int os_dirname(char_u *buf, size_t len) return OK; } +/// Check if the given path is a directory and not a symlink to a directory. +/// @return `true` if `name` is a directory and NOT a symlink to a directory. +/// `false` if `name` is not a directory or if an error occurred. +bool os_isrealdir(const char_u *name) + FUNC_ATTR_NONNULL_ALL +{ + uv_fs_t request; + if (uv_fs_lstat(&fs_loop, &request, (char *)name, NULL) != kLibuvSuccess) { + return false; + } + if (S_ISLNK(request.statbuf.st_mode)) { + return false; + } else { + return S_ISDIR(request.statbuf.st_mode); + } +} + /// Check if the given path is a directory or not. /// /// @return `true` if `fname` is a directory. diff --git a/src/nvim/tempfile.c b/src/nvim/tempfile.c index 882dbe32f2..5b6268168d 100644 --- a/src/nvim/tempfile.c +++ b/src/nvim/tempfile.c @@ -63,7 +63,7 @@ int delete_recursive(char_u *name) { int result = 0; - if (os_isdir(name)) { + if (os_isrealdir(name)) { snprintf((char *)NameBuff, MAXPATHL, "%s/*", name); char_u **files; diff --git a/src/nvim/version.c b/src/nvim/version.c index 2828442611..235d74de76 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -250,7 +250,7 @@ static int included_patches[] = { // 1117, // 1116, // 1115 NA - // 1114, + 1114, 1113, 1112, // 1111, diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua index 01b06d606f..b524af3338 100644 --- a/test/functional/legacy/delete_spec.lua +++ b/test/functional/legacy/delete_spec.lua @@ -1,5 +1,6 @@ local helpers = require('test.functional.helpers') local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local source = helpers.source local eq, eval, execute, expect = helpers.eq, helpers.eval, helpers.execute, helpers.expect describe('Test for delete()', function() @@ -38,4 +39,60 @@ describe('Test for delete()', function() eq(0, eval("isdirectory('Xdir1')")) eq(-1, eval("delete('Xdir1', 'd')")) end) + + it('symlink delete', function() + source([[ + split Xfile + call setline(1, ['a', 'b']) + wq + silent !ln -s Xfile Xlink + ]]) + -- Delete the link, not the file + eq(0, eval("delete('Xlink')")) + eq(-1, eval("delete('Xlink')")) + eq(0, eval("delete('Xfile')")) + end) + + it('symlink directory delete', function() + execute("call mkdir('Xdir1')") + execute("silent !ln -s Xdir1 Xlink") + eq(1, eval("isdirectory('Xdir1')")) + eq(1, eval("isdirectory('Xlink')")) + -- Delete the link, not the directory + eq(0, eval("delete('Xlink')")) + eq(-1, eval("delete('Xlink')")) + eq(0, eval("delete('Xdir1', 'd')")) + end) + + it('symlink recursive delete', function() + source([[ + call mkdir('Xdir3') + call mkdir('Xdir3/subdir') + call mkdir('Xdir4') + split Xdir3/Xfile + call setline(1, ['a', 'b']) + w + w Xdir3/subdir/Xfile + w Xdir4/Xfile + close + silent !ln -s ../Xdir4 Xdir3/Xlink + ]]) + + eq(1, eval("isdirectory('Xdir3')")) + eq(eval("['a', 'b']"), eval("readfile('Xdir3/Xfile')")) + eq(1, eval("isdirectory('Xdir3/subdir')")) + eq(eval("['a', 'b']"), eval("readfile('Xdir3/subdir/Xfile')")) + eq(1, eval("isdirectory('Xdir4')")) + eq(1, eval("isdirectory('Xdir3/Xlink')")) + eq(eval("['a', 'b']"), eval("readfile('Xdir4/Xfile')")) + + eq(0, eval("delete('Xdir3', 'rf')")) + eq(0, eval("isdirectory('Xdir3')")) + eq(-1, eval("delete('Xdir3', 'd')")) + -- symlink is deleted, not the directory it points to + eq(1, eval("isdirectory('Xdir4')")) + eq(eval("['a', 'b']"), eval("readfile('Xdir4/Xfile')")) + eq(0, eval("delete('Xdir4/Xfile')")) + eq(0, eval("delete('Xdir4', 'd')")) + end) end) |