summaryrefslogtreecommitdiff
path: root/compat/mingw.c
diff options
context:
space:
mode:
authorKarsten Blees <blees@dcon.de>2018-10-23 10:23:21 (GMT)
committerJunio C Hamano <gitster@pobox.com>2018-10-24 04:18:14 (GMT)
commitd75e6973539f1f99561ae6f42a81f024497e3dfa (patch)
tree79b005112f9282155e2bd2fcfb8f78f8d673344c /compat/mingw.c
parent7bf198388645995d72073d331fd2bc00243ffea1 (diff)
downloadgit-d75e6973539f1f99561ae6f42a81f024497e3dfa.zip
git-d75e6973539f1f99561ae6f42a81f024497e3dfa.tar.gz
git-d75e6973539f1f99561ae6f42a81f024497e3dfa.tar.bz2
mingw: replace MSVCRT's fstat() with a Win32-based implementation
fstat() is the only stat-related CRT function for which we don't have a full replacement yet (and thus the only reason to stick with MSVCRT's 'struct stat' definition). Fully implement fstat(), in preparation of implementing a POSIX 2013 compatible 'struct stat' with nanosecond-precision file times. This allows us also to implement some clever code to handle pipes and character devices in our own way. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'compat/mingw.c')
-rw-r--r--compat/mingw.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index d2e7d86..07fc0b7 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -771,20 +771,31 @@ int mingw_stat(const char *file_name, struct stat *buf)
int mingw_fstat(int fd, struct stat *buf)
{
HANDLE fh = (HANDLE)_get_osfhandle(fd);
+ DWORD avail, type = GetFileType(fh) & ~FILE_TYPE_REMOTE;
- if (fh == INVALID_HANDLE_VALUE) {
- errno = EBADF;
- return -1;
- }
- /* direct non-file handles to MS's fstat() */
- if (GetFileType(fh) != FILE_TYPE_DISK)
- return _fstati64(fd, buf);
+ switch (type) {
+ case FILE_TYPE_DISK:
+ return get_file_info_by_handle(fh, buf);
- if (!get_file_info_by_handle(fh, buf))
+ case FILE_TYPE_CHAR:
+ case FILE_TYPE_PIPE:
+ /* initialize stat fields */
+ memset(buf, 0, sizeof(*buf));
+ buf->st_nlink = 1;
+
+ if (type == FILE_TYPE_CHAR) {
+ buf->st_mode = _S_IFCHR;
+ } else {
+ buf->st_mode = _S_IFIFO;
+ if (PeekNamedPipe(fh, NULL, 0, NULL, &avail, NULL))
+ buf->st_size = avail;
+ }
return 0;
- errno = EBADF;
- return -1;
+ default:
+ errno = EBADF;
+ return -1;
+ }
}
static inline void time_t_to_filetime(time_t t, FILETIME *ft)