|
|
d6ba96 |
To: vim_dev@googlegroups.com
|
|
|
d6ba96 |
Subject: Patch 7.4.039
|
|
|
d6ba96 |
Fcc: outbox
|
|
|
d6ba96 |
From: Bram Moolenaar <Bram@moolenaar.net>
|
|
|
d6ba96 |
Mime-Version: 1.0
|
|
|
d6ba96 |
Content-Type: text/plain; charset=UTF-8
|
|
|
d6ba96 |
Content-Transfer-Encoding: 8bit
|
|
|
d6ba96 |
------------
|
|
|
d6ba96 |
|
|
|
d6ba96 |
Patch 7.4.039
|
|
|
d6ba96 |
Problem: MS-Windows: MSCV10 and earlier can't handle symlinks to a
|
|
|
d6ba96 |
directory properly.
|
|
|
d6ba96 |
Solution: Add stat_symlink_aware() and wstat_symlink_aware(). (Ken Takata)
|
|
|
d6ba96 |
Files: src/os_mswin.c, src/os_win32.c, src/os_win32.h
|
|
|
d6ba96 |
|
|
|
d6ba96 |
|
|
|
d6ba96 |
*** ../vim-7.4.038/src/os_mswin.c 2013-08-30 16:51:15.000000000 +0200
|
|
|
d6ba96 |
--- src/os_mswin.c 2013-09-25 19:09:53.000000000 +0200
|
|
|
d6ba96 |
***************
|
|
|
d6ba96 |
*** 498,503 ****
|
|
|
d6ba96 |
--- 498,595 ----
|
|
|
d6ba96 |
}
|
|
|
d6ba96 |
}
|
|
|
d6ba96 |
|
|
|
d6ba96 |
+ static int
|
|
|
d6ba96 |
+ stat_symlink_aware(const char *name, struct stat *stp)
|
|
|
d6ba96 |
+ {
|
|
|
d6ba96 |
+ #if defined(_MSC_VER) && _MSC_VER < 1700
|
|
|
d6ba96 |
+ /* Work around for VC10 or earlier. stat() can't handle symlinks properly.
|
|
|
d6ba96 |
+ * VC9 or earlier: stat() doesn't support a symlink at all. It retrieves
|
|
|
d6ba96 |
+ * status of a symlink itself.
|
|
|
d6ba96 |
+ * VC10: stat() supports a symlink to a normal file, but it doesn't support
|
|
|
d6ba96 |
+ * a symlink to a directory (always returns an error). */
|
|
|
d6ba96 |
+ WIN32_FIND_DATA findData;
|
|
|
d6ba96 |
+ HANDLE hFind, h;
|
|
|
d6ba96 |
+ DWORD attr = 0;
|
|
|
d6ba96 |
+ BOOL is_symlink = FALSE;
|
|
|
d6ba96 |
+
|
|
|
d6ba96 |
+ hFind = FindFirstFile(name, &findData);
|
|
|
d6ba96 |
+ if (hFind != INVALID_HANDLE_VALUE)
|
|
|
d6ba96 |
+ {
|
|
|
d6ba96 |
+ attr = findData.dwFileAttributes;
|
|
|
d6ba96 |
+ if ((attr & FILE_ATTRIBUTE_REPARSE_POINT)
|
|
|
d6ba96 |
+ && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
|
|
|
d6ba96 |
+ is_symlink = TRUE;
|
|
|
d6ba96 |
+ FindClose(hFind);
|
|
|
d6ba96 |
+ }
|
|
|
d6ba96 |
+ if (is_symlink)
|
|
|
d6ba96 |
+ {
|
|
|
d6ba96 |
+ h = CreateFile(name, FILE_READ_ATTRIBUTES,
|
|
|
d6ba96 |
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
|
|
d6ba96 |
+ OPEN_EXISTING,
|
|
|
d6ba96 |
+ (attr & FILE_ATTRIBUTE_DIRECTORY)
|
|
|
d6ba96 |
+ ? FILE_FLAG_BACKUP_SEMANTICS : 0,
|
|
|
d6ba96 |
+ NULL);
|
|
|
d6ba96 |
+ if (h != INVALID_HANDLE_VALUE)
|
|
|
d6ba96 |
+ {
|
|
|
d6ba96 |
+ int fd, n;
|
|
|
d6ba96 |
+
|
|
|
d6ba96 |
+ fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
|
|
|
d6ba96 |
+ n = _fstat(fd, (struct _stat*)stp);
|
|
|
d6ba96 |
+ _close(fd);
|
|
|
d6ba96 |
+ return n;
|
|
|
d6ba96 |
+ }
|
|
|
d6ba96 |
+ }
|
|
|
d6ba96 |
+ #endif
|
|
|
d6ba96 |
+ return stat(name, stp);
|
|
|
d6ba96 |
+ }
|
|
|
d6ba96 |
+
|
|
|
d6ba96 |
+ #ifdef FEAT_MBYTE
|
|
|
d6ba96 |
+ static int
|
|
|
d6ba96 |
+ wstat_symlink_aware(const WCHAR *name, struct _stat *stp)
|
|
|
d6ba96 |
+ {
|
|
|
d6ba96 |
+ # if defined(_MSC_VER) && _MSC_VER < 1700
|
|
|
d6ba96 |
+ /* Work around for VC10 or earlier. _wstat() can't handle symlinks properly.
|
|
|
d6ba96 |
+ * VC9 or earlier: _wstat() doesn't support a symlink at all. It retrieves
|
|
|
d6ba96 |
+ * status of a symlink itself.
|
|
|
d6ba96 |
+ * VC10: _wstat() supports a symlink to a normal file, but it doesn't
|
|
|
d6ba96 |
+ * support a symlink to a directory (always returns an error). */
|
|
|
d6ba96 |
+ int n;
|
|
|
d6ba96 |
+ BOOL is_symlink = FALSE;
|
|
|
d6ba96 |
+ HANDLE hFind, h;
|
|
|
d6ba96 |
+ DWORD attr = 0;
|
|
|
d6ba96 |
+ WIN32_FIND_DATAW findDataW;
|
|
|
d6ba96 |
+
|
|
|
d6ba96 |
+ hFind = FindFirstFileW(name, &findDataW);
|
|
|
d6ba96 |
+ if (hFind != INVALID_HANDLE_VALUE)
|
|
|
d6ba96 |
+ {
|
|
|
d6ba96 |
+ attr = findDataW.dwFileAttributes;
|
|
|
d6ba96 |
+ if ((attr & FILE_ATTRIBUTE_REPARSE_POINT)
|
|
|
d6ba96 |
+ && (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
|
|
|
d6ba96 |
+ is_symlink = TRUE;
|
|
|
d6ba96 |
+ FindClose(hFind);
|
|
|
d6ba96 |
+ }
|
|
|
d6ba96 |
+ if (is_symlink)
|
|
|
d6ba96 |
+ {
|
|
|
d6ba96 |
+ h = CreateFileW(name, FILE_READ_ATTRIBUTES,
|
|
|
d6ba96 |
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
|
|
d6ba96 |
+ OPEN_EXISTING,
|
|
|
d6ba96 |
+ (attr & FILE_ATTRIBUTE_DIRECTORY)
|
|
|
d6ba96 |
+ ? FILE_FLAG_BACKUP_SEMANTICS : 0,
|
|
|
d6ba96 |
+ NULL);
|
|
|
d6ba96 |
+ if (h != INVALID_HANDLE_VALUE)
|
|
|
d6ba96 |
+ {
|
|
|
d6ba96 |
+ int fd;
|
|
|
d6ba96 |
+
|
|
|
d6ba96 |
+ fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
|
|
|
d6ba96 |
+ n = _fstat(fd, stp);
|
|
|
d6ba96 |
+ _close(fd);
|
|
|
d6ba96 |
+ return n;
|
|
|
d6ba96 |
+ }
|
|
|
d6ba96 |
+ }
|
|
|
d6ba96 |
+ # endif
|
|
|
d6ba96 |
+ return _wstat(name, stp);
|
|
|
d6ba96 |
+ }
|
|
|
d6ba96 |
+ #endif
|
|
|
d6ba96 |
|
|
|
d6ba96 |
/*
|
|
|
d6ba96 |
* stat() can't handle a trailing '/' or '\', remove it first.
|
|
|
d6ba96 |
***************
|
|
|
d6ba96 |
*** 534,540 ****
|
|
|
d6ba96 |
|
|
|
d6ba96 |
if (wp != NULL)
|
|
|
d6ba96 |
{
|
|
|
d6ba96 |
! n = _wstat(wp, (struct _stat *)stp);
|
|
|
d6ba96 |
vim_free(wp);
|
|
|
d6ba96 |
if (n >= 0)
|
|
|
d6ba96 |
return n;
|
|
|
d6ba96 |
--- 626,632 ----
|
|
|
d6ba96 |
|
|
|
d6ba96 |
if (wp != NULL)
|
|
|
d6ba96 |
{
|
|
|
d6ba96 |
! n = wstat_symlink_aware(wp, (struct _stat *)stp);
|
|
|
d6ba96 |
vim_free(wp);
|
|
|
d6ba96 |
if (n >= 0)
|
|
|
d6ba96 |
return n;
|
|
|
d6ba96 |
***************
|
|
|
d6ba96 |
*** 544,550 ****
|
|
|
d6ba96 |
}
|
|
|
d6ba96 |
}
|
|
|
d6ba96 |
#endif
|
|
|
d6ba96 |
! return stat(buf, stp);
|
|
|
d6ba96 |
}
|
|
|
d6ba96 |
|
|
|
d6ba96 |
#if defined(FEAT_GUI_MSWIN) || defined(PROTO)
|
|
|
d6ba96 |
--- 636,642 ----
|
|
|
d6ba96 |
}
|
|
|
d6ba96 |
}
|
|
|
d6ba96 |
#endif
|
|
|
d6ba96 |
! return stat_symlink_aware(buf, stp);
|
|
|
d6ba96 |
}
|
|
|
d6ba96 |
|
|
|
d6ba96 |
#if defined(FEAT_GUI_MSWIN) || defined(PROTO)
|
|
|
d6ba96 |
*** ../vim-7.4.038/src/os_win32.c 2013-08-30 17:29:10.000000000 +0200
|
|
|
d6ba96 |
--- src/os_win32.c 2013-09-25 19:09:53.000000000 +0200
|
|
|
d6ba96 |
***************
|
|
|
d6ba96 |
*** 78,93 ****
|
|
|
d6ba96 |
# endif
|
|
|
d6ba96 |
#endif
|
|
|
d6ba96 |
|
|
|
d6ba96 |
- /*
|
|
|
d6ba96 |
- * Reparse Point
|
|
|
d6ba96 |
- */
|
|
|
d6ba96 |
- #ifndef FILE_ATTRIBUTE_REPARSE_POINT
|
|
|
d6ba96 |
- # define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
|
|
|
d6ba96 |
- #endif
|
|
|
d6ba96 |
- #ifndef IO_REPARSE_TAG_SYMLINK
|
|
|
d6ba96 |
- # define IO_REPARSE_TAG_SYMLINK 0xA000000C
|
|
|
d6ba96 |
- #endif
|
|
|
d6ba96 |
-
|
|
|
d6ba96 |
/* Record all output and all keyboard & mouse input */
|
|
|
d6ba96 |
/* #define MCH_WRITE_DUMP */
|
|
|
d6ba96 |
|
|
|
d6ba96 |
--- 78,83 ----
|
|
|
d6ba96 |
*** ../vim-7.4.038/src/os_win32.h 2013-07-21 17:53:13.000000000 +0200
|
|
|
d6ba96 |
--- src/os_win32.h 2013-09-25 19:09:53.000000000 +0200
|
|
|
d6ba96 |
***************
|
|
|
d6ba96 |
*** 130,135 ****
|
|
|
d6ba96 |
--- 130,148 ----
|
|
|
d6ba96 |
# define DFLT_MAXMEMTOT (5*1024) /* use up to 5 Mbyte for Vim */
|
|
|
d6ba96 |
#endif
|
|
|
d6ba96 |
|
|
|
d6ba96 |
+ /*
|
|
|
d6ba96 |
+ * Reparse Point
|
|
|
d6ba96 |
+ */
|
|
|
d6ba96 |
+ #ifndef FILE_ATTRIBUTE_REPARSE_POINT
|
|
|
d6ba96 |
+ # define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
|
|
|
d6ba96 |
+ #endif
|
|
|
d6ba96 |
+ #ifndef IO_REPARSE_TAG_MOUNT_POINT
|
|
|
d6ba96 |
+ # define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
|
|
|
d6ba96 |
+ #endif
|
|
|
d6ba96 |
+ #ifndef IO_REPARSE_TAG_SYMLINK
|
|
|
d6ba96 |
+ # define IO_REPARSE_TAG_SYMLINK 0xA000000C
|
|
|
d6ba96 |
+ #endif
|
|
|
d6ba96 |
+
|
|
|
d6ba96 |
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
|
|
d6ba96 |
/* Support for __try / __except. All versions of MSVC and Borland C are
|
|
|
d6ba96 |
* expected to have this. Any other compilers that support it? */
|
|
|
d6ba96 |
*** ../vim-7.4.038/src/version.c 2013-09-25 18:54:20.000000000 +0200
|
|
|
d6ba96 |
--- src/version.c 2013-09-25 19:08:55.000000000 +0200
|
|
|
d6ba96 |
***************
|
|
|
d6ba96 |
*** 740,741 ****
|
|
|
d6ba96 |
--- 740,743 ----
|
|
|
d6ba96 |
{ /* Add new patch number below this line */
|
|
|
d6ba96 |
+ /**/
|
|
|
d6ba96 |
+ 39,
|
|
|
d6ba96 |
/**/
|
|
|
d6ba96 |
|
|
|
d6ba96 |
--
|
|
|
d6ba96 |
A cow comes flying over the battlements, lowing aggressively. The cow
|
|
|
d6ba96 |
lands on GALAHAD'S PAGE, squashing him completely.
|
|
|
d6ba96 |
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
|
|
|
d6ba96 |
|
|
|
d6ba96 |
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
|
|
|
d6ba96 |
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
|
|
|
d6ba96 |
\\\ an exciting new programming language -- http://www.Zimbu.org ///
|
|
|
d6ba96 |
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|