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:
@@ -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)
|
||||||
|
Reference in New Issue
Block a user