From 96010cc96848dc2ef731115d5e459e343bdaf024 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 24 Jan 2024 10:22:31 -0500 Subject: Ensure stdin, stdout, stderr FILE streams are open on Windows Extend commit c85524a94a (Ensure stdin, stdout, and stderr pipes are always open, 2019-05-02, v3.15.0-rc1~171^2) to cover the `stdin`, `stdout`, and `stderr` FILE streams from ``. Issue: #25625 --- Source/cmSystemTools.cxx | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index bd914e5..18ca85b 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2377,43 +2377,30 @@ cmSystemTools::WaitForLineResult cmSystemTools::WaitForLine( } #ifdef _WIN32 -static void EnsureStdPipe(DWORD fd) +static void EnsureStdPipe(int stdFd, DWORD nStdHandle, FILE* stream, + const wchar_t* mode) { - if (GetStdHandle(fd) != INVALID_HANDLE_VALUE) { + if (fileno(stream) >= 0) { return; } - SECURITY_ATTRIBUTES sa; - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = nullptr; - sa.bInheritHandle = TRUE; - - HANDLE h = CreateFileW( - L"NUL", - fd == STD_INPUT_HANDLE ? FILE_GENERIC_READ - : FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, nullptr); - - if (h == INVALID_HANDLE_VALUE) { - LPSTR message = nullptr; - DWORD size = FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&message, 0, nullptr); - std::string msg = std::string(message, size); - LocalFree(message); - std::cerr << "failed to open NUL for missing stdio pipe: " << msg; + _close(stdFd); + _wfreopen(L"NUL", mode, stream); + int fd = fileno(stream); + if (fd < 0) { + perror("failed to open NUL for missing stdio pipe"); abort(); } - - SetStdHandle(fd, h); + if (fd != stdFd) { + _dup2(fd, stdFd); + } + SetStdHandle(nStdHandle, reinterpret_cast(_get_osfhandle(fd))); } void cmSystemTools::EnsureStdPipes() { - EnsureStdPipe(STD_INPUT_HANDLE); - EnsureStdPipe(STD_OUTPUT_HANDLE); - EnsureStdPipe(STD_ERROR_HANDLE); + EnsureStdPipe(0, STD_INPUT_HANDLE, stdin, L"rb"); + EnsureStdPipe(1, STD_OUTPUT_HANDLE, stdout, L"wb"); + EnsureStdPipe(2, STD_ERROR_HANDLE, stderr, L"wb"); } #else static void EnsureStdPipe(int fd) -- cgit v0.12