0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

updated for version 7.4.039

Problem:    MS-Windows: MSCV10 and earlier can't handle symlinks to a
            directory properly.
Solution:   Add stat_symlink_aware() and wstat_symlink_aware(). (Ken Takata)
This commit is contained in:
Bram Moolenaar 2013-09-25 19:13:38 +02:00
parent 134bf07ca0
commit 2ee95f7d13
4 changed files with 109 additions and 12 deletions

View File

@ -498,6 +498,98 @@ 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.
* 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). */
WIN32_FIND_DATA findData;
HANDLE hFind, h;
DWORD attr = 0;
BOOL is_symlink = FALSE;
hFind = FindFirstFile(name, &findData);
if (hFind != INVALID_HANDLE_VALUE)
{
attr = findData.dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT)
&& (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
is_symlink = TRUE;
FindClose(hFind);
}
if (is_symlink)
{
h = CreateFile(name, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING,
(attr & FILE_ATTRIBUTE_DIRECTORY)
? FILE_FLAG_BACKUP_SEMANTICS : 0,
NULL);
if (h != INVALID_HANDLE_VALUE)
{
int fd, n;
fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
n = _fstat(fd, (struct _stat*)stp);
_close(fd);
return n;
}
}
#endif
return stat(name, stp);
}
#ifdef FEAT_MBYTE
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.
* 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). */
int n;
BOOL is_symlink = FALSE;
HANDLE hFind, h;
DWORD attr = 0;
WIN32_FIND_DATAW findDataW;
hFind = FindFirstFileW(name, &findDataW);
if (hFind != INVALID_HANDLE_VALUE)
{
attr = findDataW.dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT)
&& (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
is_symlink = TRUE;
FindClose(hFind);
}
if (is_symlink)
{
h = CreateFileW(name, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING,
(attr & FILE_ATTRIBUTE_DIRECTORY)
? FILE_FLAG_BACKUP_SEMANTICS : 0,
NULL);
if (h != INVALID_HANDLE_VALUE)
{
int fd;
fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
n = _fstat(fd, stp);
_close(fd);
return n;
}
}
# endif
return _wstat(name, stp);
}
#endif
/*
* stat() can't handle a trailing '/' or '\', remove it first.
@ -534,7 +626,7 @@ vim_stat(const char *name, struct stat *stp)
if (wp != NULL)
{
n = _wstat(wp, (struct _stat *)stp);
n = wstat_symlink_aware(wp, (struct _stat *)stp);
vim_free(wp);
if (n >= 0)
return n;
@ -544,7 +636,7 @@ vim_stat(const char *name, struct stat *stp)
}
}
#endif
return stat(buf, stp);
return stat_symlink_aware(buf, stp);
}
#if defined(FEAT_GUI_MSWIN) || defined(PROTO)

View File

@ -78,16 +78,6 @@
# endif
#endif
/*
* Reparse Point
*/
#ifndef FILE_ATTRIBUTE_REPARSE_POINT
# define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
#endif
#ifndef IO_REPARSE_TAG_SYMLINK
# define IO_REPARSE_TAG_SYMLINK 0xA000000C
#endif
/* Record all output and all keyboard & mouse input */
/* #define MCH_WRITE_DUMP */

View File

@ -130,6 +130,19 @@
# define DFLT_MAXMEMTOT (5*1024) /* use up to 5 Mbyte for Vim */
#endif
/*
* Reparse Point
*/
#ifndef FILE_ATTRIBUTE_REPARSE_POINT
# define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
#endif
#ifndef IO_REPARSE_TAG_MOUNT_POINT
# define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
#endif
#ifndef IO_REPARSE_TAG_SYMLINK
# define IO_REPARSE_TAG_SYMLINK 0xA000000C
#endif
#if defined(_MSC_VER) || defined(__BORLANDC__)
/* Support for __try / __except. All versions of MSVC and Borland C are
* expected to have this. Any other compilers that support it? */

View File

@ -738,6 +738,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
39,
/**/
38,
/**/