diff --git a/src/port/win32stat.c b/src/port/win32stat.c index 2ad8ee1359..8b97959223 100644 --- a/src/port/win32stat.c +++ b/src/port/win32stat.c @@ -289,6 +289,7 @@ int _pgfstat64(int fileno, struct stat *buf) { HANDLE hFile = (HANDLE) _get_osfhandle(fileno); + char path[MAX_PATH]; if (hFile == INVALID_HANDLE_VALUE || buf == NULL) { @@ -301,6 +302,34 @@ _pgfstat64(int fileno, struct stat *buf) * ERROR_DELETE_PENDING. */ + /*-------------------- + * Function GetFileInformationByHandle() can not work with + * stdin/stdout/stderr. Need to emulate call _fstat64() for them. + * Two important points: + * 1) we should compare "fileno" with result of _fileno() function + * (not with 0,1,2). It is need if standard stream was closed. Function + * _fileno() returns -1 in this case; + * 2) we call GetFinalPathNameByHandleA() for case "fileno" was reopened + * and associated to file - after call + * "freopen(OutputFileName, "a", stdout)" for example. + * (After freopen() function GetFinalPathNameByHandleA() returns length + * of "path" > 0 and we should process "stdout" handle as file, without + * emulation). + *-------------------- + */ + if ((fileno == _fileno(stdin) || + fileno == _fileno(stdout) || + fileno == _fileno(stderr)) && + !GetFinalPathNameByHandleA(hFile, path, MAX_PATH, VOLUME_NAME_NT)) + { + memset(buf, 0, sizeof(*buf)); + buf->st_mode = _S_IFCHR; + buf->st_dev = fileno; + buf->st_rdev = fileno; + buf->st_nlink = 1; + return 0; + } + return fileinfo_to_stat(hFile, buf); }