Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c4d2392

Browse files
author
Edward Thomson
committed
fstat: use our custom stat
1 parent aadad40 commit c4d2392

File tree

3 files changed

+62
-12
lines changed

3 files changed

+62
-12
lines changed

src/win32/posix.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
typedef SOCKET GIT_SOCKET;
1818

1919
#define p_lseek(f,n,w) _lseeki64(f, n, w)
20-
#define p_fstat(f,b) _fstat64(f, b)
20+
21+
extern int p_fstat(int fd, struct stat *buf);
2122
extern int p_lstat(const char *file_name, struct stat *buf);
22-
extern int p_stat(const char* path, struct stat* buf);
23+
extern int p_stat(const char* path, struct stat *buf);
2324

2425
extern int p_utimes(const char *filename, const struct p_timeval times[2]);
2526
extern int p_futimes(int fd, const struct p_timeval times[2]);

src/win32/posix_w32.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,22 @@ static int follow_and_lstat_link(git_win32_path path, struct stat* buf)
398398
return lstat_w(target_w, buf, false);
399399
}
400400

401+
int p_fstat(int fd, struct stat *buf)
402+
{
403+
BY_HANDLE_FILE_INFORMATION fhInfo;
404+
405+
HANDLE fh = (HANDLE)_get_osfhandle(fd);
406+
407+
if (fh == INVALID_HANDLE_VALUE ||
408+
!GetFileInformationByHandle(fh, &fhInfo)) {
409+
errno = EBADF;
410+
return -1;
411+
}
412+
413+
git_win32__file_information_to_stat(buf, &fhInfo);
414+
return 0;
415+
}
416+
401417
int p_stat(const char* path, struct stat* buf)
402418
{
403419
git_win32_path path_w;

src/win32/w32_util.h

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,32 +105,65 @@ GIT_INLINE(void) git_win32__timeval_to_filetime(
105105
ft->dwLowDateTime = (ticks & 0xffffffffLL);
106106
}
107107

108-
GIT_INLINE(int) git_win32__file_attribute_to_stat(
108+
GIT_INLINE(void) git_win32__stat_init(
109109
struct stat *st,
110-
const WIN32_FILE_ATTRIBUTE_DATA *attrdata,
111-
const wchar_t *path)
110+
DWORD dwFileAttributes,
111+
DWORD nFileSizeHigh,
112+
DWORD nFileSizeLow,
113+
FILETIME ftCreationTime,
114+
FILETIME ftLastAccessTime,
115+
FILETIME ftLastWriteTime)
112116
{
113117
mode_t mode = S_IREAD;
114118

115-
if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
119+
memset(st, 0, sizeof(struct stat));
120+
121+
if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
116122
mode |= S_IFDIR;
117123
else
118124
mode |= S_IFREG;
119125

120-
if ((attrdata->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
126+
if ((dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
121127
mode |= S_IWRITE;
122128

123129
st->st_ino = 0;
124130
st->st_gid = 0;
125131
st->st_uid = 0;
126132
st->st_nlink = 1;
127133
st->st_mode = mode;
128-
st->st_size = ((git_off_t)attrdata->nFileSizeHigh << 32) + attrdata->nFileSizeLow;
134+
st->st_size = ((git_off_t)nFileSizeHigh << 32) + nFileSizeLow;
129135
st->st_dev = _getdrive() - 1;
130136
st->st_rdev = st->st_dev;
131-
git_win32__filetime_to_timespec(&(attrdata->ftLastAccessTime), &(st->st_atim));
132-
git_win32__filetime_to_timespec(&(attrdata->ftLastWriteTime), &(st->st_mtim));
133-
git_win32__filetime_to_timespec(&(attrdata->ftCreationTime), &(st->st_ctim));
137+
git_win32__filetime_to_timespec(&ftLastAccessTime, &(st->st_atim));
138+
git_win32__filetime_to_timespec(&ftLastWriteTime, &(st->st_mtim));
139+
git_win32__filetime_to_timespec(&ftCreationTime, &(st->st_ctim));
140+
}
141+
142+
GIT_INLINE(void) git_win32__file_information_to_stat(
143+
struct stat *st,
144+
const BY_HANDLE_FILE_INFORMATION *fileinfo)
145+
{
146+
git_win32__stat_init(st,
147+
fileinfo->dwFileAttributes,
148+
fileinfo->nFileSizeHigh,
149+
fileinfo->nFileSizeLow,
150+
fileinfo->ftCreationTime,
151+
fileinfo->ftLastAccessTime,
152+
fileinfo->ftLastWriteTime);
153+
}
154+
155+
GIT_INLINE(int) git_win32__file_attribute_to_stat(
156+
struct stat *st,
157+
const WIN32_FILE_ATTRIBUTE_DATA *attrdata,
158+
const wchar_t *path)
159+
{
160+
git_win32__stat_init(st,
161+
attrdata->dwFileAttributes,
162+
attrdata->nFileSizeHigh,
163+
attrdata->nFileSizeLow,
164+
attrdata->ftCreationTime,
165+
attrdata->ftLastAccessTime,
166+
attrdata->ftLastWriteTime);
134167

135168
if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && path) {
136169
git_win32_path target;
@@ -139,7 +172,7 @@ GIT_INLINE(int) git_win32__file_attribute_to_stat(
139172
st->st_mode = (st->st_mode & ~S_IFMT) | S_IFLNK;
140173

141174
/* st_size gets the UTF-8 length of the target name, in bytes,
142-
* not counting the NULL terminator */
175+
* not counting the NULL terminator */
143176
if ((st->st_size = git__utf16_to_8(NULL, 0, target)) < 0) {
144177
giterr_set(GITERR_OS, "Could not convert reparse point name for '%s'", path);
145178
return -1;

0 commit comments

Comments
 (0)