@@ -698,9 +698,9 @@ int mingw_lstat(const char *file_name, struct stat *buf)
698698 buf -> st_size = S_ISLNK (buf -> st_mode ) ? MAX_LONG_PATH :
699699 fdata .nFileSizeLow | (((off_t ) fdata .nFileSizeHigh ) << 32 );
700700 buf -> st_dev = buf -> st_rdev = 0 ; /* not used by Git */
701- buf -> st_atime = filetime_to_time_t (& (fdata .ftLastAccessTime ));
702- buf -> st_mtime = filetime_to_time_t (& (fdata .ftLastWriteTime ));
703- buf -> st_ctime = filetime_to_time_t (& (fdata .ftCreationTime ));
701+ filetime_to_timespec (& (fdata .ftLastAccessTime ), & ( buf -> st_atim ));
702+ filetime_to_timespec (& (fdata .ftLastWriteTime ), & ( buf -> st_mtim ));
703+ filetime_to_timespec (& (fdata .ftCreationTime ), & ( buf -> st_ctim ));
704704 return 0 ;
705705 }
706706error :
@@ -745,9 +745,9 @@ static int get_file_info_by_handle(HANDLE hnd, struct stat *buf)
745745 buf -> st_nlink = 1 ;
746746 buf -> st_mode = file_attr_to_st_mode (fdata .dwFileAttributes , 0 );
747747 buf -> st_size = fdata .nFileSizeLow | (((off_t ) fdata .nFileSizeHigh ) << 32 );
748- buf -> st_atime = filetime_to_time_t (& (fdata .ftLastAccessTime ));
749- buf -> st_mtime = filetime_to_time_t (& (fdata .ftLastWriteTime ));
750- buf -> st_ctime = filetime_to_time_t (& (fdata .ftCreationTime ));
748+ filetime_to_timespec (& (fdata .ftLastAccessTime ), & ( buf -> st_atim ));
749+ filetime_to_timespec (& (fdata .ftLastWriteTime ), & ( buf -> st_mtim ));
750+ filetime_to_timespec (& (fdata .ftCreationTime ), & ( buf -> st_ctim ));
751751 return 0 ;
752752}
753753
@@ -775,18 +775,31 @@ int mingw_stat(const char *file_name, struct stat *buf)
775775int mingw_fstat (int fd , struct stat * buf )
776776{
777777 HANDLE fh = (HANDLE )_get_osfhandle (fd );
778- if (fh == INVALID_HANDLE_VALUE ) {
778+ DWORD avail , type = GetFileType (fh ) & ~FILE_TYPE_REMOTE ;
779+
780+ switch (type ) {
781+ case FILE_TYPE_DISK :
782+ return get_file_info_by_handle (fh , buf );
783+
784+ case FILE_TYPE_CHAR :
785+ case FILE_TYPE_PIPE :
786+ /* initialize stat fields */
787+ memset (buf , 0 , sizeof (* buf ));
788+ buf -> st_nlink = 1 ;
789+
790+ if (type == FILE_TYPE_CHAR ) {
791+ buf -> st_mode = _S_IFCHR ;
792+ } else {
793+ buf -> st_mode = _S_IFIFO ;
794+ if (PeekNamedPipe (fh , NULL , 0 , NULL , & avail , NULL ))
795+ buf -> st_size = avail ;
796+ }
797+ return 0 ;
798+
799+ default :
779800 errno = EBADF ;
780801 return -1 ;
781802 }
782- /* direct non-file handles to MS's fstat() */
783- if (GetFileType (fh ) != FILE_TYPE_DISK )
784- return _fstati64 (fd , buf );
785-
786- if (!get_file_info_by_handle (fh , buf ))
787- return 0 ;
788- errno = EBADF ;
789- return -1 ;
790803}
791804
792805static inline void time_t_to_filetime (time_t t , FILETIME * ft )
0 commit comments