1 To: vim_dev@googlegroups.com
4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
11 Problem: MS-Windows: rename() might delete the file if the name differs but
12 it's actually the same file.
13 Solution: Use the file handle to check if it's the same file. (Yukihiro
15 Files: src/if_cscope.c, src/fileio.c, src/os_win32.c,
16 src/proto/os_win32.pro, src/vim.h
19 *** ../vim-7.3.171/src/if_cscope.c 2011-03-03 15:01:25.000000000 +0100
20 --- src/if_cscope.c 2011-05-05 16:16:38.000000000 +0200
27 BY_HANDLE_FILE_INFORMATION bhfi;
29 - vim_memset(&bhfi, 0, sizeof(bhfi));
30 /* On windows 9x GetFileInformationByHandle doesn't work, so skip it */
33 ! hFile = CreateFile(fname, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
34 ! FILE_ATTRIBUTE_NORMAL, NULL);
35 ! if (hFile == INVALID_HANDLE_VALUE)
39 char *cant_msg = _("E625: cannot open cscope database: %s");
44 BY_HANDLE_FILE_INFORMATION bhfi;
46 /* On windows 9x GetFileInformationByHandle doesn't work, so skip it */
49 ! switch (win32_fileinfo(fname, &bhfi))
51 + case FILEINFO_ENC_FAIL: /* enc_to_utf16() failed */
52 + case FILEINFO_READ_FAIL: /* CreateFile() failed */
55 char *cant_msg = _("E625: cannot open cscope database: %s");
58 (void)EMSG2(cant_msg, fname);
62 ! if (!GetFileInformationByHandle(hFile, &bhfi))
66 (void)EMSG(_("E626: cannot get cscope database information"));
74 (void)EMSG2(cant_msg, fname);
78 ! case FILEINFO_INFO_FAIL: /* GetFileInformationByHandle() failed */
80 (void)EMSG(_("E626: cannot get cscope database information"));
86 *** ../vim-7.3.171/src/fileio.c 2011-04-11 21:35:03.000000000 +0200
87 --- src/fileio.c 2011-05-05 16:22:22.000000000 +0200
96 + BY_HANDLE_FILE_INFORMATION info1, info2;
98 + /* It's possible for the source and destination to be the same file.
99 + * In that case go through a temp file name. This makes rename("foo",
100 + * "./foo") a no-op (in a complicated way). */
101 + if (win32_fileinfo(from, &info1) == FILEINFO_OK
102 + && win32_fileinfo(to, &info2) == FILEINFO_OK
103 + && info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
104 + && info1.nFileIndexHigh == info2.nFileIndexHigh
105 + && info1.nFileIndexLow == info2.nFileIndexLow)
106 + use_tmp_file = TRUE;
110 #if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
112 *** ../vim-7.3.171/src/os_win32.c 2011-02-01 13:48:47.000000000 +0100
113 --- src/os_win32.c 2011-05-05 16:24:17.000000000 +0200
117 mch_is_linked(char_u *fname)
121 ! BY_HANDLE_FILE_INFORMATION inf;
125 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
126 wn = enc_to_utf16(fname, NULL);
129 hFile = CreateFileW(wn, /* file name */
130 GENERIC_READ, /* access mode */
131 ! 0, /* share mode */
132 NULL, /* security descriptor */
133 OPEN_EXISTING, /* creation disposition */
134 ! 0, /* file attributes */
135 NULL); /* handle to template file */
136 if (hFile == INVALID_HANDLE_VALUE
137 ! && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
139 /* Retry with non-wide function (for Windows 98). */
143 mch_is_linked(char_u *fname)
145 + BY_HANDLE_FILE_INFORMATION info;
147 + return win32_fileinfo(fname, &info) == FILEINFO_OK
148 + && info.nNumberOfLinks > 1;
152 + * Get the by-handle-file-information for "fname".
153 + * Returns FILEINFO_OK when OK.
154 + * returns FILEINFO_ENC_FAIL when enc_to_utf16() failed.
155 + * Returns FILEINFO_READ_FAIL when CreateFile() failed.
156 + * Returns FILEINFO_INFO_FAIL when GetFileInformationByHandle() failed.
159 + win32_fileinfo(char_u *fname, BY_HANDLE_FILE_INFORMATION *info)
162 ! int res = FILEINFO_READ_FAIL;
166 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
168 wn = enc_to_utf16(fname, NULL);
170 + res = FILEINFO_ENC_FAIL;
174 hFile = CreateFileW(wn, /* file name */
175 GENERIC_READ, /* access mode */
176 ! FILE_SHARE_READ | FILE_SHARE_WRITE, /* share mode */
177 NULL, /* security descriptor */
178 OPEN_EXISTING, /* creation disposition */
179 ! FILE_FLAG_BACKUP_SEMANTICS, /* file attributes */
180 NULL); /* handle to template file */
181 if (hFile == INVALID_HANDLE_VALUE
182 ! && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
184 /* Retry with non-wide function (for Windows 98). */
189 hFile = CreateFile(fname, /* file name */
190 GENERIC_READ, /* access mode */
191 ! 0, /* share mode */
192 NULL, /* security descriptor */
193 OPEN_EXISTING, /* creation disposition */
194 ! 0, /* file attributes */
195 NULL); /* handle to template file */
197 if (hFile != INVALID_HANDLE_VALUE)
199 ! if (GetFileInformationByHandle(hFile, &inf) != 0
200 ! && inf.nNumberOfLinks > 1)
207 hFile = CreateFile(fname, /* file name */
208 GENERIC_READ, /* access mode */
209 ! FILE_SHARE_READ | FILE_SHARE_WRITE, /* share mode */
210 NULL, /* security descriptor */
211 OPEN_EXISTING, /* creation disposition */
212 ! FILE_FLAG_BACKUP_SEMANTICS, /* file attributes */
213 NULL); /* handle to template file */
215 if (hFile != INVALID_HANDLE_VALUE)
217 ! if (GetFileInformationByHandle(hFile, info) != 0)
220 ! res = FILEINFO_INFO_FAIL;
224 *** ../vim-7.3.171/src/proto/os_win32.pro 2010-10-23 14:02:48.000000000 +0200
225 --- src/proto/os_win32.pro 2011-05-05 16:17:42.000000000 +0200
229 void mch_hide __ARGS((char_u *name));
230 int mch_isdir __ARGS((char_u *name));
231 int mch_is_linked __ARGS((char_u *fname));
232 + int win32_fileinfo __ARGS((char_u *name, BY_HANDLE_FILE_INFORMATION *lpFileInfo));
233 int mch_writable __ARGS((char_u *name));
234 int mch_can_exe __ARGS((char_u *name));
235 int mch_nodetype __ARGS((char_u *name));
236 *** ../vim-7.3.171/src/vim.h 2011-04-11 21:35:03.000000000 +0200
237 --- src/vim.h 2011-05-05 16:16:57.000000000 +0200
241 #define KEYLEN_PART_MAP -2 /* keylen value for incomplete mapping */
242 #define KEYLEN_REMOVED 9999 /* keylen value for removed sequence */
244 + /* Return values from win32_fileinfo(). */
245 + #define FILEINFO_OK 0
246 + #define FILEINFO_ENC_FAIL 1 /* enc_to_utf16() failed */
247 + #define FILEINFO_READ_FAIL 2 /* CreateFile() failed */
248 + #define FILEINFO_INFO_FAIL 3 /* GetFileInformationByHandle() failed */
251 *** ../vim-7.3.171/src/version.c 2011-05-05 14:26:37.000000000 +0200
252 --- src/version.c 2011-05-05 16:39:35.000000000 +0200
256 { /* Add new patch number below this line */
262 Q: What is a patch 22?
263 A: A patch you need to include to make it possible to include patches.
265 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
266 /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
267 \\\ an exciting new programming language -- http://www.Zimbu.org ///
268 \\\ help me help AIDS victims -- http://ICCF-Holland.org ///