Created
September 18, 2017 23:53
-
-
Save corford/5d67e808ec11e1fab44dd0796e12eb60 to your computer and use it in GitHub Desktop.
mingw.c
This file contains hidden or 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 for: %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("dwFileAttributes: %lu", fdata.dwFileAttributes); | |
error("dwReserved0: %lu", findbuf.dwReserved0); | |
error("translated attribs: %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