vim-patch:7.4.1114

Problem:    delete() does not work well with symbolic links.
Solution:   Recognize symbolik links.

43a34f9f74
This commit is contained in:
Jurica Bradaric
2016-02-28 12:44:59 +01:00
parent 50a7517a6d
commit 88a735166b
5 changed files with 80 additions and 5 deletions

View File

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

View File

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

View File

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

View File

@@ -250,7 +250,7 @@ static int included_patches[] = {
// 1117,
// 1116,
// 1115 NA
// 1114,
1114,
1113,
1112,
// 1111,

View File

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