From: Karsten Blees <bl...@dcon.de>

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 <bl...@dcon.de>
Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de>
---
 compat/mingw.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index d2e7d86db..07fc0b79a 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)
-- 
gitgitgadget

Reply via email to