diff options
author | Edward Thomson <ethomson@github.com> | 2016-02-11 15:41:07 -0800 |
---|---|---|
committer | Edward Thomson <ethomson@github.com> | 2016-02-16 11:50:45 +0000 |
commit | c4d23928c3801041f392adc173ffa62a8249ee25 (patch) | |
tree | 08f5874229c2b320444d170f09a3552e49adc247 | |
parent | aadad4059224c686f1ee1b451e3a29c76b5c4b45 (diff) | |
download | libgit2-c4d23928c3801041f392adc173ffa62a8249ee25.tar.gz |
fstat: use our custom `stat`
-rw-r--r-- | src/win32/posix.h | 5 | ||||
-rw-r--r-- | src/win32/posix_w32.c | 16 | ||||
-rw-r--r-- | src/win32/w32_util.h | 53 |
3 files changed, 62 insertions, 12 deletions
diff --git a/src/win32/posix.h b/src/win32/posix.h index 732128bb0..5fab267c2 100644 --- a/src/win32/posix.h +++ b/src/win32/posix.h @@ -17,9 +17,10 @@ typedef SOCKET GIT_SOCKET; #define p_lseek(f,n,w) _lseeki64(f, n, w) -#define p_fstat(f,b) _fstat64(f, b) + +extern int p_fstat(int fd, struct stat *buf); extern int p_lstat(const char *file_name, struct stat *buf); -extern int p_stat(const char* path, struct stat* buf); +extern int p_stat(const char* path, struct stat *buf); extern int p_utimes(const char *filename, const struct p_timeval times[2]); extern int p_futimes(int fd, const struct p_timeval times[2]); diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index d743e8fc8..fea634b00 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -398,6 +398,22 @@ static int follow_and_lstat_link(git_win32_path path, struct stat* buf) return lstat_w(target_w, buf, false); } +int p_fstat(int fd, struct stat *buf) +{ + BY_HANDLE_FILE_INFORMATION fhInfo; + + HANDLE fh = (HANDLE)_get_osfhandle(fd); + + if (fh == INVALID_HANDLE_VALUE || + !GetFileInformationByHandle(fh, &fhInfo)) { + errno = EBADF; + return -1; + } + + git_win32__file_information_to_stat(buf, &fhInfo); + return 0; +} + int p_stat(const char* path, struct stat* buf) { git_win32_path path_w; diff --git a/src/win32/w32_util.h b/src/win32/w32_util.h index b095939a1..2e475e5e9 100644 --- a/src/win32/w32_util.h +++ b/src/win32/w32_util.h @@ -105,19 +105,25 @@ GIT_INLINE(void) git_win32__timeval_to_filetime( ft->dwLowDateTime = (ticks & 0xffffffffLL); } -GIT_INLINE(int) git_win32__file_attribute_to_stat( +GIT_INLINE(void) git_win32__stat_init( struct stat *st, - const WIN32_FILE_ATTRIBUTE_DATA *attrdata, - const wchar_t *path) + DWORD dwFileAttributes, + DWORD nFileSizeHigh, + DWORD nFileSizeLow, + FILETIME ftCreationTime, + FILETIME ftLastAccessTime, + FILETIME ftLastWriteTime) { mode_t mode = S_IREAD; - if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + memset(st, 0, sizeof(struct stat)); + + if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) mode |= S_IFDIR; else mode |= S_IFREG; - if ((attrdata->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0) + if ((dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0) mode |= S_IWRITE; st->st_ino = 0; @@ -125,12 +131,39 @@ GIT_INLINE(int) git_win32__file_attribute_to_stat( st->st_uid = 0; st->st_nlink = 1; st->st_mode = mode; - st->st_size = ((git_off_t)attrdata->nFileSizeHigh << 32) + attrdata->nFileSizeLow; + st->st_size = ((git_off_t)nFileSizeHigh << 32) + nFileSizeLow; st->st_dev = _getdrive() - 1; st->st_rdev = st->st_dev; - git_win32__filetime_to_timespec(&(attrdata->ftLastAccessTime), &(st->st_atim)); - git_win32__filetime_to_timespec(&(attrdata->ftLastWriteTime), &(st->st_mtim)); - git_win32__filetime_to_timespec(&(attrdata->ftCreationTime), &(st->st_ctim)); + git_win32__filetime_to_timespec(&ftLastAccessTime, &(st->st_atim)); + git_win32__filetime_to_timespec(&ftLastWriteTime, &(st->st_mtim)); + git_win32__filetime_to_timespec(&ftCreationTime, &(st->st_ctim)); +} + +GIT_INLINE(void) git_win32__file_information_to_stat( + struct stat *st, + const BY_HANDLE_FILE_INFORMATION *fileinfo) +{ + git_win32__stat_init(st, + fileinfo->dwFileAttributes, + fileinfo->nFileSizeHigh, + fileinfo->nFileSizeLow, + fileinfo->ftCreationTime, + fileinfo->ftLastAccessTime, + fileinfo->ftLastWriteTime); +} + +GIT_INLINE(int) git_win32__file_attribute_to_stat( + struct stat *st, + const WIN32_FILE_ATTRIBUTE_DATA *attrdata, + const wchar_t *path) +{ + git_win32__stat_init(st, + attrdata->dwFileAttributes, + attrdata->nFileSizeHigh, + attrdata->nFileSizeLow, + attrdata->ftCreationTime, + attrdata->ftLastAccessTime, + attrdata->ftLastWriteTime); if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && path) { git_win32_path target; @@ -139,7 +172,7 @@ GIT_INLINE(int) git_win32__file_attribute_to_stat( st->st_mode = (st->st_mode & ~S_IFMT) | S_IFLNK; /* st_size gets the UTF-8 length of the target name, in bytes, - * not counting the NULL terminator */ + * not counting the NULL terminator */ if ((st->st_size = git__utf16_to_8(NULL, 0, target)) < 0) { giterr_set(GITERR_OS, "Could not convert reparse point name for '%s'", path); return -1; |