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>
Karsten Blees committed
Oct 23, 2018 at 03:23 UTC
d75e6973539f1f99561ae6f42a81f024497e3dfa
1 file changed
+21
-10
compat/mingw.c
+21
-10
@@ -771,20 +771,31 @@ int mingw_stat(const char *file_name, struct stat *buf)
771
int mingw_fstat(int fd, struct stat *buf)
772
{
773
HANDLE fh = (HANDLE)_get_osfhandle(fd);
774
+ DWORD avail, type = GetFileType(fh) & ~FILE_TYPE_REMOTE;
775
775
- if (fh == INVALID_HANDLE_VALUE) {
776
- errno = EBADF;
777
- return -1;
778
- }
779
- /* direct non-file handles to MS's fstat() */
780
- if (GetFileType(fh) != FILE_TYPE_DISK)
781
- return _fstati64(fd, buf);
776
+ switch (type) {
777
+ case FILE_TYPE_DISK:
778
+ return get_file_info_by_handle(fh, buf);
779
783
- if (!get_file_info_by_handle(fh, buf))
780
+ case FILE_TYPE_CHAR:
781
+ case FILE_TYPE_PIPE:
782
+ /* initialize stat fields */
783
+ memset(buf, 0, sizeof(*buf));
784
+ buf->st_nlink = 1;
785
+
786
+ if (type == FILE_TYPE_CHAR) {
787
+ buf->st_mode = _S_IFCHR;
788
+ } else {
789
+ buf->st_mode = _S_IFIFO;
790
+ if (PeekNamedPipe(fh, NULL, 0, NULL, &avail, NULL))
791
+ buf->st_size = avail;
792
+ }
793
return 0;
794
786
- errno = EBADF;
787
- return -1;
795
+ default:
796
+ errno = EBADF;
797
+ return -1;
798
+ }
799
}
800
801
static inline void time_t_to_filetime(time_t t, FILETIME *ft)