Hi,

When passing a symlink to a directory, getftype() returns "file" on Windows.
I think it should return "dir" as same as a junction. (Returning "link"
might cause trouble, because many people don't care about symlinks on Windows.)
This is caused by a bug of VC runtime which was fixed by VC2015. VC2013 or
earlier and MinGW have this bug. (I don't know about other old compilers
like BCC.)
Attached patch fixes the problem.

Note: Creating a symlink on Windows needs admin rights, so we cannot write
tests for this.

Regards,
Ken Takata

-- 
-- 
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.
# HG changeset patch
# Parent 8bb4ca7fba402830d8b7f05de44651dfbe23a048
# Parent  5953485bada9104ea42638c7a3e79fea94b7f927

diff --git a/src/os_mswin.c b/src/os_mswin.c
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -506,12 +506,16 @@ slash_adjust(p)
     static int
 stat_symlink_aware(const char *name, struct stat *stp)
 {
-#if defined(_MSC_VER) && _MSC_VER < 1700
-    /* Work around for VC10 or earlier. stat() can't handle symlinks properly.
+#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__)
+    /* Work around for VC12 or earlier (and MinGW). stat() can't handle
+     * symlinks properly.
      * VC9 or earlier: stat() doesn't support a symlink at all. It retrieves
      * status of a symlink itself.
      * VC10: stat() supports a symlink to a normal file, but it doesn't support
-     * a symlink to a directory (always returns an error). */
+     * a symlink to a directory (always returns an error).
+     * VC11 and VC12: stat() doesn't return an error for a symlink to a
+     * directory, but it doesn't set S_IFDIR flag.
+     * MinGW: Same as VC9. */
     WIN32_FIND_DATA	findData;
     HANDLE		hFind, h;
     DWORD		attr = 0;
@@ -540,6 +544,8 @@ stat_symlink_aware(const char *name, str
 
 	    fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY);
 	    n = _fstat(fd, (struct _stat*)stp);
+	    if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY))
+		stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR;
 	    _close(fd);
 	    return n;
 	}
@@ -552,12 +558,16 @@ stat_symlink_aware(const char *name, str
     static int
 wstat_symlink_aware(const WCHAR *name, struct _stat *stp)
 {
-# if defined(_MSC_VER) && _MSC_VER < 1700
-    /* Work around for VC10 or earlier. _wstat() can't handle symlinks properly.
+# if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__)
+    /* Work around for VC12 or earlier (and MinGW). _wstat() can't handle
+     * symlinks properly.
      * VC9 or earlier: _wstat() doesn't support a symlink at all. It retrieves
      * status of a symlink itself.
      * VC10: _wstat() supports a symlink to a normal file, but it doesn't
-     * support a symlink to a directory (always returns an error). */
+     * support a symlink to a directory (always returns an error).
+     * VC11 and VC12: _wstat() doesn't return an error for a symlink to a
+     * directory, but it doesn't set S_IFDIR flag.
+     * MinGW: Same as VC9. */
     int			n;
     BOOL		is_symlink = FALSE;
     HANDLE		hFind, h;
@@ -587,6 +597,8 @@ wstat_symlink_aware(const WCHAR *name, s
 
 	    fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY);
 	    n = _fstat(fd, stp);
+	    if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY))
+		stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR;
 	    _close(fd);
 	    return n;
 	}

Raspunde prin e-mail lui