1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-16 22:37:30 +08:00

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 `<stdio.h>`.

Issue: #25625
This commit is contained in:
Brad King
2024-01-24 10:22:31 -05:00
parent 8533a8505c
commit 96010cc968

View File

@@ -2377,43 +2377,30 @@ cmSystemTools::WaitForLineResult cmSystemTools::WaitForLine(
} }
#ifdef _WIN32 #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; return;
} }
SECURITY_ATTRIBUTES sa; _close(stdFd);
sa.nLength = sizeof(sa); _wfreopen(L"NUL", mode, stream);
sa.lpSecurityDescriptor = nullptr; int fd = fileno(stream);
sa.bInheritHandle = TRUE; if (fd < 0) {
perror("failed to open NUL for missing stdio pipe");
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;
abort(); abort();
} }
if (fd != stdFd) {
SetStdHandle(fd, h); _dup2(fd, stdFd);
}
SetStdHandle(nStdHandle, reinterpret_cast<HANDLE>(_get_osfhandle(fd)));
} }
void cmSystemTools::EnsureStdPipes() void cmSystemTools::EnsureStdPipes()
{ {
EnsureStdPipe(STD_INPUT_HANDLE); EnsureStdPipe(0, STD_INPUT_HANDLE, stdin, L"rb");
EnsureStdPipe(STD_OUTPUT_HANDLE); EnsureStdPipe(1, STD_OUTPUT_HANDLE, stdout, L"wb");
EnsureStdPipe(STD_ERROR_HANDLE); EnsureStdPipe(2, STD_ERROR_HANDLE, stderr, L"wb");
} }
#else #else
static void EnsureStdPipe(int fd) static void EnsureStdPipe(int fd)