summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-01-17 22:15:16 +0100
committerBram Moolenaar <Bram@vim.org>2016-01-17 22:15:16 +0100
commit203258c3ad2966cc9d08b3805b103333988b30b7 (patch)
treebc95043f2a838d99b1205e548a73588429fa279f
parent021b593e7ed6c7111cbf189744ad1e5d6c4a7d79 (diff)
downloadvim-203258c3ad2966cc9d08b3805b103333988b30b7.zip
patch 7.4.1128
Problem: MS-Windows: delete() does not recognize junctions. Solution: Add mch_isrealdir() for MS-Windows. Update mch_is_symbolic_link(). (Ken Takata)
-rw-r--r--src/fileio.c8
-rw-r--r--src/os_win32.c34
-rw-r--r--src/proto/os_win32.pro1
-rw-r--r--src/version.c2
4 files changed, 32 insertions, 13 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 55337d682..cd538095f 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7297,14 +7297,10 @@ delete_recursive(char_u *name)
/* 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
+# if defined(UNIX) || defined(WIN32)
mch_isrealdir(name)
-# else
+# else
mch_isdir(name)
-# endif
# endif
)
{
diff --git a/src/os_win32.c b/src/os_win32.c
index a47ffaf18..b4f5fa466 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -3130,6 +3130,17 @@ mch_isdir(char_u *name)
}
/*
+ * 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(char_u *name)
+{
+ return mch_isdir(name) && !mch_is_symbolic_link(name);
+}
+
+/*
* Create directory "name".
* Return 0 on success, -1 on error.
*/
@@ -3190,10 +3201,10 @@ mch_is_hard_link(char_u *fname)
}
/*
- * Return TRUE if file "fname" is a symbolic link.
+ * Return TRUE if "name" is a symbolic link (or a junction).
*/
int
-mch_is_symbolic_link(char_u *fname)
+mch_is_symbolic_link(char_u *name)
{
HANDLE hFind;
int res = FALSE;
@@ -3204,7 +3215,7 @@ mch_is_symbolic_link(char_u *fname)
WIN32_FIND_DATAW findDataW;
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
- wn = enc_to_utf16(fname, NULL);
+ wn = enc_to_utf16(name, NULL);
if (wn != NULL)
{
hFind = FindFirstFileW(wn, &findDataW);
@@ -3213,7 +3224,7 @@ mch_is_symbolic_link(char_u *fname)
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
/* Retry with non-wide function (for Windows 98). */
- hFind = FindFirstFile(fname, &findDataA);
+ hFind = FindFirstFile(name, &findDataA);
if (hFind != INVALID_HANDLE_VALUE)
{
fileFlags = findDataA.dwFileAttributes;
@@ -3229,7 +3240,7 @@ mch_is_symbolic_link(char_u *fname)
else
#endif
{
- hFind = FindFirstFile(fname, &findDataA);
+ hFind = FindFirstFile(name, &findDataA);
if (hFind != INVALID_HANDLE_VALUE)
{
fileFlags = findDataA.dwFileAttributes;
@@ -3241,7 +3252,8 @@ mch_is_symbolic_link(char_u *fname)
FindClose(hFind);
if ((fileFlags & FILE_ATTRIBUTE_REPARSE_POINT)
- && reparseTag == IO_REPARSE_TAG_SYMLINK)
+ && (reparseTag == IO_REPARSE_TAG_SYMLINK
+ || reparseTag == IO_REPARSE_TAG_MOUNT_POINT))
res = TRUE;
return res;
@@ -5839,7 +5851,8 @@ mch_delay(
/*
- * this version of remove is not scared by a readonly (backup) file
+ * This version of remove is not scared by a readonly (backup) file.
+ * This can also remove a symbolic link like Unix.
* Return 0 for success, -1 for failure.
*/
int
@@ -5850,6 +5863,13 @@ mch_remove(char_u *name)
int n;
#endif
+ /*
+ * On Windows, deleting a directory's symbolic link is done by
+ * RemoveDirectory(): mch_rmdir. It seems unnatural, but it is fact.
+ */
+ if (mch_isdir(name) && mch_is_symbolic_link(name))
+ return mch_rmdir(name);
+
win32_setattrs(name, FILE_ATTRIBUTE_NORMAL);
#ifdef FEAT_MBYTE
diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro
index 7cdd15677..b3acb4f4c 100644
--- a/src/proto/os_win32.pro
+++ b/src/proto/os_win32.pro
@@ -21,6 +21,7 @@ int mch_setperm __ARGS((char_u *name, long perm));
void mch_hide __ARGS((char_u *name));
int mch_ishidden __ARGS((char_u *name));
int mch_isdir __ARGS((char_u *name));
+int mch_isrealdir __ARGS((char_u *name));
int mch_mkdir __ARGS((char_u *name));
int mch_rmdir __ARGS((char_u *name));
int mch_is_hard_link __ARGS((char_u *fname));
diff --git a/src/version.c b/src/version.c
index 61393c2e4..5e5a31990 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1128,
+/**/
1127,
/**/
1126,