mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
updated for version 7.3.172
Problem: MS-Windows: rename() might delete the file if the name differs but it's actually the same file. Solution: Use the file handle to check if it's the same file. (Yukihiro Nakadaira)
This commit is contained in:
15
src/fileio.c
15
src/fileio.c
@@ -6555,6 +6555,21 @@ vim_rename(from, to)
|
|||||||
use_tmp_file = TRUE;
|
use_tmp_file = TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WIN3264
|
||||||
|
{
|
||||||
|
BY_HANDLE_FILE_INFORMATION info1, info2;
|
||||||
|
|
||||||
|
/* It's possible for the source and destination to be the same file.
|
||||||
|
* In that case go through a temp file name. This makes rename("foo",
|
||||||
|
* "./foo") a no-op (in a complicated way). */
|
||||||
|
if (win32_fileinfo(from, &info1) == FILEINFO_OK
|
||||||
|
&& win32_fileinfo(to, &info2) == FILEINFO_OK
|
||||||
|
&& info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
|
||||||
|
&& info1.nFileIndexHigh == info2.nFileIndexHigh
|
||||||
|
&& info1.nFileIndexLow == info2.nFileIndexLow)
|
||||||
|
use_tmp_file = TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
|
#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
|
||||||
if (use_tmp_file)
|
if (use_tmp_file)
|
||||||
|
@@ -1412,17 +1412,15 @@ cs_insert_filelist(fname, ppath, flags, sb)
|
|||||||
{
|
{
|
||||||
short i, j;
|
short i, j;
|
||||||
#ifndef UNIX
|
#ifndef UNIX
|
||||||
HANDLE hFile;
|
|
||||||
BY_HANDLE_FILE_INFORMATION bhfi;
|
BY_HANDLE_FILE_INFORMATION bhfi;
|
||||||
|
|
||||||
vim_memset(&bhfi, 0, sizeof(bhfi));
|
|
||||||
/* On windows 9x GetFileInformationByHandle doesn't work, so skip it */
|
/* On windows 9x GetFileInformationByHandle doesn't work, so skip it */
|
||||||
if (!mch_windows95())
|
if (!mch_windows95())
|
||||||
{
|
{
|
||||||
hFile = CreateFile(fname, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
|
switch (win32_fileinfo(fname, &bhfi))
|
||||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
{
|
||||||
|
case FILEINFO_ENC_FAIL: /* enc_to_utf16() failed */
|
||||||
|
case FILEINFO_READ_FAIL: /* CreateFile() failed */
|
||||||
if (p_csverbose)
|
if (p_csverbose)
|
||||||
{
|
{
|
||||||
char *cant_msg = _("E625: cannot open cscope database: %s");
|
char *cant_msg = _("E625: cannot open cscope database: %s");
|
||||||
@@ -1438,15 +1436,12 @@ cs_insert_filelist(fname, ppath, flags, sb)
|
|||||||
(void)EMSG2(cant_msg, fname);
|
(void)EMSG2(cant_msg, fname);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
if (!GetFileInformationByHandle(hFile, &bhfi))
|
case FILEINFO_INFO_FAIL: /* GetFileInformationByHandle() failed */
|
||||||
{
|
|
||||||
CloseHandle(hFile);
|
|
||||||
if (p_csverbose)
|
if (p_csverbose)
|
||||||
(void)EMSG(_("E626: cannot get cscope database information"));
|
(void)EMSG(_("E626: cannot get cscope database information"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CloseHandle(hFile);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -2644,26 +2644,45 @@ mch_isdir(char_u *name)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
mch_is_linked(char_u *fname)
|
mch_is_linked(char_u *fname)
|
||||||
|
{
|
||||||
|
BY_HANDLE_FILE_INFORMATION info;
|
||||||
|
|
||||||
|
return win32_fileinfo(fname, &info) == FILEINFO_OK
|
||||||
|
&& info.nNumberOfLinks > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the by-handle-file-information for "fname".
|
||||||
|
* Returns FILEINFO_OK when OK.
|
||||||
|
* returns FILEINFO_ENC_FAIL when enc_to_utf16() failed.
|
||||||
|
* Returns FILEINFO_READ_FAIL when CreateFile() failed.
|
||||||
|
* Returns FILEINFO_INFO_FAIL when GetFileInformationByHandle() failed.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
win32_fileinfo(char_u *fname, BY_HANDLE_FILE_INFORMATION *info)
|
||||||
{
|
{
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
int res = 0;
|
int res = FILEINFO_READ_FAIL;
|
||||||
BY_HANDLE_FILE_INFORMATION inf;
|
|
||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
WCHAR *wn = NULL;
|
WCHAR *wn = NULL;
|
||||||
|
|
||||||
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
|
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
|
||||||
|
{
|
||||||
wn = enc_to_utf16(fname, NULL);
|
wn = enc_to_utf16(fname, NULL);
|
||||||
|
if (wn == NULL)
|
||||||
|
res = FILEINFO_ENC_FAIL;
|
||||||
|
}
|
||||||
if (wn != NULL)
|
if (wn != NULL)
|
||||||
{
|
{
|
||||||
hFile = CreateFileW(wn, /* file name */
|
hFile = CreateFileW(wn, /* file name */
|
||||||
GENERIC_READ, /* access mode */
|
GENERIC_READ, /* access mode */
|
||||||
0, /* share mode */
|
FILE_SHARE_READ | FILE_SHARE_WRITE, /* share mode */
|
||||||
NULL, /* security descriptor */
|
NULL, /* security descriptor */
|
||||||
OPEN_EXISTING, /* creation disposition */
|
OPEN_EXISTING, /* creation disposition */
|
||||||
0, /* file attributes */
|
FILE_FLAG_BACKUP_SEMANTICS, /* file attributes */
|
||||||
NULL); /* handle to template file */
|
NULL); /* handle to template file */
|
||||||
if (hFile == INVALID_HANDLE_VALUE
|
if (hFile == INVALID_HANDLE_VALUE
|
||||||
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||||
{
|
{
|
||||||
/* Retry with non-wide function (for Windows 98). */
|
/* Retry with non-wide function (for Windows 98). */
|
||||||
vim_free(wn);
|
vim_free(wn);
|
||||||
@@ -2674,17 +2693,18 @@ mch_is_linked(char_u *fname)
|
|||||||
#endif
|
#endif
|
||||||
hFile = CreateFile(fname, /* file name */
|
hFile = CreateFile(fname, /* file name */
|
||||||
GENERIC_READ, /* access mode */
|
GENERIC_READ, /* access mode */
|
||||||
0, /* share mode */
|
FILE_SHARE_READ | FILE_SHARE_WRITE, /* share mode */
|
||||||
NULL, /* security descriptor */
|
NULL, /* security descriptor */
|
||||||
OPEN_EXISTING, /* creation disposition */
|
OPEN_EXISTING, /* creation disposition */
|
||||||
0, /* file attributes */
|
FILE_FLAG_BACKUP_SEMANTICS, /* file attributes */
|
||||||
NULL); /* handle to template file */
|
NULL); /* handle to template file */
|
||||||
|
|
||||||
if (hFile != INVALID_HANDLE_VALUE)
|
if (hFile != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
if (GetFileInformationByHandle(hFile, &inf) != 0
|
if (GetFileInformationByHandle(hFile, info) != 0)
|
||||||
&& inf.nNumberOfLinks > 1)
|
res = FILEINFO_OK;
|
||||||
res = 1;
|
else
|
||||||
|
res = FILEINFO_INFO_FAIL;
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,6 +21,7 @@ int mch_setperm __ARGS((char_u *name, long perm));
|
|||||||
void mch_hide __ARGS((char_u *name));
|
void mch_hide __ARGS((char_u *name));
|
||||||
int mch_isdir __ARGS((char_u *name));
|
int mch_isdir __ARGS((char_u *name));
|
||||||
int mch_is_linked __ARGS((char_u *fname));
|
int mch_is_linked __ARGS((char_u *fname));
|
||||||
|
int win32_fileinfo __ARGS((char_u *name, BY_HANDLE_FILE_INFORMATION *lpFileInfo));
|
||||||
int mch_writable __ARGS((char_u *name));
|
int mch_writable __ARGS((char_u *name));
|
||||||
int mch_can_exe __ARGS((char_u *name));
|
int mch_can_exe __ARGS((char_u *name));
|
||||||
int mch_nodetype __ARGS((char_u *name));
|
int mch_nodetype __ARGS((char_u *name));
|
||||||
|
@@ -714,6 +714,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
172,
|
||||||
/**/
|
/**/
|
||||||
171,
|
171,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -2217,4 +2217,10 @@ typedef int VimClipboard; /* This is required for the prototypes. */
|
|||||||
#define KEYLEN_PART_MAP -2 /* keylen value for incomplete mapping */
|
#define KEYLEN_PART_MAP -2 /* keylen value for incomplete mapping */
|
||||||
#define KEYLEN_REMOVED 9999 /* keylen value for removed sequence */
|
#define KEYLEN_REMOVED 9999 /* keylen value for removed sequence */
|
||||||
|
|
||||||
|
/* Return values from win32_fileinfo(). */
|
||||||
|
#define FILEINFO_OK 0
|
||||||
|
#define FILEINFO_ENC_FAIL 1 /* enc_to_utf16() failed */
|
||||||
|
#define FILEINFO_READ_FAIL 2 /* CreateFile() failed */
|
||||||
|
#define FILEINFO_INFO_FAIL 3 /* GetFileInformationByHandle() failed */
|
||||||
|
|
||||||
#endif /* VIM__H */
|
#endif /* VIM__H */
|
||||||
|
Reference in New Issue
Block a user