From 407184db12af0a7689e73824ade6f2d2cbeaaa0c Mon Sep 17 00:00:00 2001 From: Koval Dmitry Date: Wed, 17 Nov 2021 13:23:50 +0300 Subject: [PATCH] Fixed Windows stat() emulation: working with streams --- src/port/win32stat.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/port/win32stat.c b/src/port/win32stat.c index 2ad8ee1359..230bd093ed 100644 --- a/src/port/win32stat.c +++ b/src/port/win32stat.c @@ -112,7 +112,7 @@ fileattr_to_unixmode(int attr) * Convert WIN32 file information (from a HANDLE) to a struct stat. */ static int -fileinfo_to_stat(HANDLE hFile, struct stat *buf) +fileinfo_to_stat(HANDLE hFile, int fileno, const char *name, struct stat *buf) { BY_HANDLE_FILE_INFORMATION fiData; @@ -124,7 +124,25 @@ fileinfo_to_stat(HANDLE hFile, struct stat *buf) */ if (!GetFileInformationByHandle(hFile, &fiData)) { - _dosmaperr(GetLastError()); + DWORD error = GetLastError(); + + switch (error) + { + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_FUNCTION: + case ERROR_NOT_SUPPORTED: + + /* + * Object is other than real file (stdout, for example). So + * need to call _fstat64 in this case. "struct stat" should + * match "struct __stat64", see "struct stat" definition. + */ + if (fileno >= 0) + return _fstat64(fileno, (struct __stat64 *) buf); + else if (name) + return _stat64(name, (struct __stat64 *) buf); + } + _dosmaperr(error); return -1; } @@ -276,7 +294,7 @@ _pgstat64(const char *name, struct stat *buf) } /* At last we can invoke fileinfo_to_stat */ - ret = fileinfo_to_stat(hFile, buf); + ret = fileinfo_to_stat(hFile, -1, name, buf); CloseHandle(hFile); return ret; @@ -301,7 +319,7 @@ _pgfstat64(int fileno, struct stat *buf) * ERROR_DELETE_PENDING. */ - return fileinfo_to_stat(hFile, buf); + return fileinfo_to_stat(hFile, fileno, NULL, buf); } #endif /* WIN32 */ -- 2.31.0.windows.1