mirror of
https://github.com/git/git.git
synced 2026-01-11 13:23:12 +09:00
mingw: let mingw_lstat() error early upon problems with reparse points
When obtaining lstat information for reparse points, we need to call `FindFirstFile()` in addition to `GetFileInformationEx()` to obtain the type of the reparse point (symlink, mount point etc.). However, currently there is no error handling whatsoever if `FindFirstFile()` fails. Call `FindFirstFile()` before modifying the `stat *buf` output parameter and error out if the call fails. Note: The `FindFirstFile()` return value includes all the data that we get from `GetFileAttributesEx()`, so we could replace `GetFileAttributesEx()` with `FindFirstFile()`. We don't do that because `GetFileAttributesEx()` is about twice as fast for single files. I.e. we only pay the extra cost of calling `FindFirstFile()` in the rare case that we encounter a reparse point. Please also note that the indentation the remaining reparse point code changed, and hence the best way to look at this diff is with `--color-moved -w`. That code was _not_ moved because a subsequent commit will move it to an altogether different function, anyway. Signed-off-by: Karsten Blees <karsten.blees@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
882e5e0528
commit
2c37842ff9
@ -920,6 +920,7 @@ static int has_valid_directory_prefix(wchar_t *wfilename)
|
||||
int mingw_lstat(const char *file_name, struct stat *buf)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA fdata;
|
||||
WIN32_FIND_DATAW findbuf = { 0 };
|
||||
wchar_t wfilename[MAX_PATH];
|
||||
int wlen = xutftowcs_path(wfilename, file_name);
|
||||
if (wlen < 0)
|
||||
@ -934,6 +935,13 @@ int mingw_lstat(const char *file_name, struct stat *buf)
|
||||
}
|
||||
|
||||
if (GetFileAttributesExW(wfilename, GetFileExInfoStandard, &fdata)) {
|
||||
/* for reparse points, use FindFirstFile to get the reparse tag */
|
||||
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
HANDLE handle = FindFirstFileW(wfilename, &findbuf);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
goto error;
|
||||
FindClose(handle);
|
||||
}
|
||||
buf->st_ino = 0;
|
||||
buf->st_gid = 0;
|
||||
buf->st_uid = 0;
|
||||
@ -946,20 +954,16 @@ int mingw_lstat(const char *file_name, struct stat *buf)
|
||||
filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim));
|
||||
filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim));
|
||||
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
WIN32_FIND_DATAW findbuf;
|
||||
HANDLE handle = FindFirstFileW(wfilename, &findbuf);
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
|
||||
(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
|
||||
buf->st_mode = S_IFLNK | S_IREAD;
|
||||
if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
buf->st_mode |= S_IWRITE;
|
||||
}
|
||||
FindClose(handle);
|
||||
if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
|
||||
(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
|
||||
buf->st_mode = S_IFLNK | S_IREAD;
|
||||
if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
buf->st_mode |= S_IWRITE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
error:
|
||||
switch (GetLastError()) {
|
||||
case ERROR_ACCESS_DENIED:
|
||||
case ERROR_SHARING_VIOLATION:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user