libuv: win/spawn: add option to use parent process error mode

Backport changes from libuv v2 commit `8ad246557a` (win,process: allow
users to configure child error mode, 2024-10-17) to add the
`UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE` option.

Also use `UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE` to keep
the behavior the same as before the option was added,
all child processes would be spawned the the parent's
error mode.

Issue: #20115
This commit is contained in:
Dylan Snelgrove 2024-10-16 23:47:24 +00:00 committed by Brad King
parent 728f40d4bf
commit 0f515c2d26
7 changed files with 26 additions and 3 deletions

View File

@ -122,6 +122,9 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
#else
static_cast<void>(affinity);
#endif
#if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV)
options.flags = UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE;
#endif
status =
uv_read_start(pipe_reader, &cmProcess::OnAllocateCB, &cmProcess::OnReadCB);

View File

@ -341,6 +341,9 @@ void cmUVProcessChain::InternalData::SpawnProcess(
(UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 48) || \
!defined(CMAKE_USE_SYSTEM_LIBUV)
options.flags |= UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME;
#endif
#if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV)
options.flags |= UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE;
#endif
if (!this->Builder->WorkingDirectory.empty()) {
options.cwd = this->Builder->WorkingDirectory.c_str();

View File

@ -250,6 +250,9 @@ bool cmUVReadOnlyProcess::start(uv_loop_t* uv_loop,
this->UVOptions_.args = const_cast<char**>(this->CommandPtr_.data());
this->UVOptions_.cwd = this->Setup_.WorkingDirectory.c_str();
this->UVOptions_.flags = UV_PROCESS_WINDOWS_HIDE;
#if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV)
this->UVOptions_.flags |= UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE;
#endif
this->UVOptions_.stdio_count =
static_cast<int>(this->UVOptionsStdIO_.size());
this->UVOptions_.stdio = this->UVOptionsStdIO_.data();

View File

@ -106,6 +106,9 @@ static bool writeDataToStreamProcess(uv_loop_t& loop,
options.file = cmakeCommand;
options.args = const_cast<char**>(processArgs.data());
options.flags = UV_PROCESS_WINDOWS_HIDE;
#if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV)
options.flags |= UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE;
#endif
options.stdio = stdio.data();
options.stdio_count = static_cast<int>(stdio.size());
options.exit_cb = [](uv_process_t* handle, int64_t exitStatus,

View File

@ -1087,7 +1087,13 @@ enum uv_process_flags {
* search for the exact file name before trying variants with
* extensions like '.exe' or '.cmd'.
*/
UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7)
UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7),
/*
* Spawn the child process with the error mode of its parent.
* This option is only meaningful on Windows systems. On Unix
* it is silently ignored.
*/
UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE = (1 << 8)
};
/*

View File

@ -1033,7 +1033,8 @@ int uv_spawn(uv_loop_t* loop,
UV_PROCESS_WINDOWS_HIDE |
UV_PROCESS_WINDOWS_HIDE_CONSOLE |
UV_PROCESS_WINDOWS_HIDE_GUI |
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE)));
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
QUEUE_INIT(&process->queue);

View File

@ -992,7 +992,8 @@ int uv_spawn(uv_loop_t* loop,
UV_PROCESS_WINDOWS_HIDE |
UV_PROCESS_WINDOWS_HIDE_CONSOLE |
UV_PROCESS_WINDOWS_HIDE_GUI |
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE)));
err = uv__utf8_to_utf16_alloc(options->file, &application);
if (err)
@ -1097,6 +1098,9 @@ int uv_spawn(uv_loop_t* loop,
startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2);
process_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_DEFAULT_ERROR_MODE;
if (options->flags & UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE) {
process_flags &= ~(CREATE_DEFAULT_ERROR_MODE);
}
if ((options->flags & UV_PROCESS_WINDOWS_HIDE_CONSOLE) ||
(options->flags & UV_PROCESS_WINDOWS_HIDE)) {