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.

Signed-off-by: Karsten Blees <[email protected]>
---
 compat/mingw.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index ba3cfb0..6d73a3d 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -532,28 +532,38 @@ int mingw_fstat(int fd, struct stat *buf)
 {
        HANDLE fh = (HANDLE)_get_osfhandle(fd);
        BY_HANDLE_FILE_INFORMATION fdata;
+       DWORD avail;
 
        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);
 
-       if (GetFileInformationByHandle(fh, &fdata)) {
-               buf->st_ino = 0;
-               buf->st_gid = 0;
-               buf->st_uid = 0;
-               buf->st_nlink = 1;
+       /* initialize stat fields */
+       memset(buf, 0, sizeof(*buf));
+       buf->st_nlink = 1;
+
+       switch (GetFileType(fh) & ~FILE_TYPE_REMOTE) {
+       case FILE_TYPE_DISK:
+               if (!GetFileInformationByHandle(fh, &fdata))
+                       break;
                buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
                buf->st_size = fdata.nFileSizeLow |
                        (((off_t)fdata.nFileSizeHigh)<<32);
-               buf->st_dev = buf->st_rdev = 0; /* not used by Git */
                buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
                buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
                buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
                return 0;
+
+       case FILE_TYPE_CHAR:
+               buf->st_mode = _S_IFCHR;
+               return 0;
+
+       case FILE_TYPE_PIPE:
+               buf->st_mode = _S_IFIFO;
+               if (PeekNamedPipe(fh, NULL, 0, NULL, &avail, NULL))
+                       buf->st_size = avail;
+               return 0;
        }
        errno = EBADF;
        return -1;
-- 
2.3.0.3.ge7778af


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to