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.
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!
+ 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.
}
/*
- * return TRUE if "name" is a directory
+ * 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
*/
#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
+}
+
static int executable_file __ARGS((char_u *name));
/*
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