Patch 7.4.1114 (after 7.4.1107)
Problem: delete() does not work well with symbolic links.
Solution: Recognize symbolik links.
Files: src/eval.c, src/fileio.c, src/os_unix.c, src/proto/os_unix.pro,
src/testdir/test_delete.vim, runtime/doc/eval.txt
*** ../vim-7.4.1113/src/eval.c 2016-01-17 14:58:43.235669165 +0100
--- src/eval.c 2016-01-17 15:35:11.980262328 +0100
***************
*** 10418,10424 ****
/* delete an empty directory */
rettv->vval.v_number = mch_rmdir(name) == 0 ? 0 : -1;
else if (STRCMP(flags, "rf") == 0)
! /* delete an directory recursively */
rettv->vval.v_number = delete_recursive(name);
else
EMSG2(_(e_invexpr2), flags);
--- 10418,10424 ----
/* delete an empty directory */
rettv->vval.v_number = mch_rmdir(name) == 0 ? 0 : -1;
else if (STRCMP(flags, "rf") == 0)
! /* delete a directory recursively */
rettv->vval.v_number = delete_recursive(name);
else
EMSG2(_(e_invexpr2), flags);
*** ../vim-7.4.1113/src/fileio.c 2016-01-16 21:26:30.493956526 +0100
--- src/fileio.c 2016-01-17 15:50:05.422716732 +0100
***************
*** 7294,7300 ****
int i;
char_u *exp;
! if (mch_isdir(name))
{
vim_snprintf((char *)NameBuff, MAXPATHL, "%s/*", name);
exp = vim_strsave(NameBuff);
--- 7294,7312 ----
int i;
char_u *exp;
! /* A symbolic link to a directory itself is deleted, not the directory it
! * points to. */
! if (
! # if defined(WIN32)
! mch_isdir(name) && !mch_is_symbolic_link(name)
! # else
! # ifdef UNIX
! mch_isrealdir(name)
! # else
! mch_isdir(name)
! # endif
! # endif
! )
{
vim_snprintf((char *)NameBuff, MAXPATHL, "%s/*", name);
exp = vim_strsave(NameBuff);
*** ../vim-7.4.1113/src/os_unix.c 2016-01-02 22:25:40.674710064 +0100
--- src/os_unix.c 2016-01-17 15:50:12.050645761 +0100
***************
*** 2994,3000 ****
}
/*
! * return TRUE if "name" is a directory
* return FALSE if "name" is not a directory
* return FALSE for error
*/
--- 2994,3000 ----
}
/*
! * return TRUE if "name" is a directory or a symlink to a directory
* return FALSE if "name" is not a directory
* return FALSE for error
*/
***************
*** 3010,3015 ****
--- 3010,3037 ----
return FALSE;
#ifdef _POSIX_SOURCE
return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
+ #else
+ return ((statb.st_mode & S_IFMT) == S_IFDIR ? TRUE : FALSE);
+ #endif
+ }
+
+ /*
+ * return TRUE if "name" is a directory, NOT a symlink to a directory
+ * return FALSE if "name" is not a directory
+ * return FALSE for error
+ */
+ int
+ mch_isrealdir(name)
+ char_u *name;
+ {
+ struct stat statb;
+
+ if (*name == NUL) /* Some stat()s don't flag "" as an error. */
+ return FALSE;
+ if (lstat((char *)name, &statb))
+ return FALSE;
+ #ifdef _POSIX_SOURCE
+ return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
#else
return ((statb.st_mode & S_IFMT) == S_IFDIR ? TRUE : FALSE);
#endif
*** ../vim-7.4.1113/src/proto/os_unix.pro 2015-12-31 19:06:56.040081995
+0100
--- src/proto/os_unix.pro 2016-01-17 15:49:42.830958226 +0100
***************
*** 41,46 ****
--- 41,47 ----
void mch_free_acl __ARGS((vim_acl_T aclent));
void mch_hide __ARGS((char_u *name));
int mch_isdir __ARGS((char_u *name));
+ int mch_isrealdir __ARGS((char_u *name));
int mch_can_exe __ARGS((char_u *name, char_u **path, int use_path));
int mch_nodetype __ARGS((char_u *name));
void mch_early_init __ARGS((void));
*** ../vim-7.4.1113/src/testdir/test_delete.vim 2016-01-16 21:26:30.501956438
+0100
--- src/testdir/test_delete.vim 2016-01-17 15:32:17.638124457 +0100
***************
*** 34,36 ****
--- 34,97 ----
call assert_false(isdirectory('Xdir1'))
call assert_equal(-1, delete('Xdir1', 'd'))
endfunc
+
+ func Test_symlink_delete()
+ if !has('unix')
+ return
+ endif
+ split Xfile
+ call setline(1, ['a', 'b'])
+ wq
+ silent !ln -s Xfile Xlink
+ " Delete the link, not the file
+ call assert_equal(0, delete('Xlink'))
+ call assert_equal(-1, delete('Xlink'))
+ call assert_equal(0, delete('Xfile'))
+ endfunc
+
+ func Test_symlink_dir_delete()
+ if !has('unix')
+ return
+ endif
+ call mkdir('Xdir1')
+ silent !ln -s Xdir1 Xlink
+ call assert_true(isdirectory('Xdir1'))
+ call assert_true(isdirectory('Xlink'))
+ " Delete the link, not the directory
+ call assert_equal(0, delete('Xlink'))
+ call assert_equal(-1, delete('Xlink'))
+ call assert_equal(0, delete('Xdir1', 'd'))
+ endfunc
+
+ func Test_symlink_recursive_delete()
+ if !has('unix')
+ return
+ endif
+ 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
+
+ call assert_true(isdirectory('Xdir3'))
+ call assert_equal(['a', 'b'], readfile('Xdir3/Xfile'))
+ call assert_true(isdirectory('Xdir3/subdir'))
+ call assert_equal(['a', 'b'], readfile('Xdir3/subdir/Xfile'))
+ call assert_true(isdirectory('Xdir4'))
+ call assert_true(isdirectory('Xdir3/Xlink'))
+ call assert_equal(['a', 'b'], readfile('Xdir4/Xfile'))
+
+ call assert_equal(0, delete('Xdir3', 'rf'))
+ call assert_false(isdirectory('Xdir3'))
+ call assert_equal(-1, delete('Xdir3', 'd'))
+ " symlink is deleted, not the directory it points to
+ call assert_true(isdirectory('Xdir4'))
+ call assert_equal(['a', 'b'], readfile('Xdir4/Xfile'))
+ call assert_equal(0, delete('Xdir4/Xfile'))
+ call assert_equal(0, delete('Xdir4', 'd'))
+ endfunc
*** ../vim-7.4.1113/runtime/doc/eval.txt 2016-01-16 21:26:30.505956395
+0100
--- runtime/doc/eval.txt 2016-01-17 15:52:03.473452633 +0100
***************
*** 2741,2753 ****
delete({fname} [, {flags}]) *delete()*
Without {flags} or with {flags} empty: Deletes the file by the
! name {fname}.
When {flags} is "d": Deletes the directory by the name
! {fname}. This fails when {fname} is not empty.
When {flags} is "rf": Deletes the directory by the name
! {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.
--- 2755,2768 ----
delete({fname} [, {flags}]) *delete()*
Without {flags} or with {flags} empty: Deletes the file by the
! name {fname}. This also works when {fname} is a symbolic link.
When {flags} is "d": Deletes the directory by the name
! {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!
! A symbolic link itself is deleted, not what it points to.
The result is a Number, which is 0 if the delete operation was
successful and -1 when the deletion failed or partly failed.
*** ../vim-7.4.1113/src/version.c 2016-01-17 14:58:43.239669122 +0100
--- src/version.c 2016-01-17 15:55:10.031454839 +0100
***************
*** 743,744 ****
--- 743,746 ----
{ /* Add new patch number below this line */
+ /**/
+ 1114,
/**/
--
If your company is not involved in something called "ISO 9000" you probably
have no idea what it is. If your company _is_ involved in ISO 9000 then you
definitely have no idea what it is.
(Scott Adams - The Dilbert principle)
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.