Created
September 15, 2017 20:31
-
-
Save corford/7a9c078fff8a8e130215f2d0568c185f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int mingw_lstat(const char *file_name, struct stat *buf) | |
{ | |
WIN32_FILE_ATTRIBUTE_DATA fdata; | |
WIN32_FIND_DATAW findbuf; | |
wchar_t wfilename[MAX_LONG_PATH]; | |
int wlen = xutftowcs_long_path(wfilename, file_name); | |
if (wlen < 0) | |
return -1; | |
/* strip trailing '/', or GetFileAttributes will fail */ | |
while (wlen && is_dir_sep(wfilename[wlen - 1])) | |
wfilename[--wlen] = 0; | |
if (!wlen) { | |
errno = ENOENT; | |
return -1; | |
} | |
error("getting attribs of: %s", file_name); | |
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; | |
buf->st_nlink = 1; | |
error("this is my flag: %x", (int)file_attr_to_st_mode(fdata.dwFileAttributes, findbuf.dwReserved0)); | |
buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes, | |
findbuf.dwReserved0); | |
buf->st_size = S_ISLNK(buf->st_mode) ? MAX_LONG_PATH : | |
fdata.nFileSizeLow | (((off_t) fdata.nFileSizeHigh) << 32); | |
buf->st_dev = buf->st_rdev = 0; /* not used by Git */ | |
filetime_to_timespec(&(fdata.ftLastAccessTime), &(buf->st_atim)); | |
filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim)); | |
filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim)); | |
return 0; | |
} | |
error: | |
switch (GetLastError()) { | |
case ERROR_ACCESS_DENIED: | |
case ERROR_SHARING_VIOLATION: | |
case ERROR_LOCK_VIOLATION: | |
case ERROR_SHARING_BUFFER_EXCEEDED: | |
errno = EACCES; | |
break; | |
case ERROR_BUFFER_OVERFLOW: | |
errno = ENAMETOOLONG; | |
break; | |
case ERROR_NOT_ENOUGH_MEMORY: | |
errno = ENOMEM; | |
break; | |
case ERROR_PATH_NOT_FOUND: | |
if (!has_valid_directory_prefix(wfilename)) { | |
errno = ENOTDIR; | |
break; | |
} | |
/* fallthru */ | |
default: | |
errno = ENOENT; | |
break; | |
} | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment