diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 2c809b6e97..b99d41c4c1 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -122,6 +122,9 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector* affinity) #else static_cast(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); diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx index b787f19943..4060a3d423 100644 --- a/Source/cmUVProcessChain.cxx +++ b/Source/cmUVProcessChain.cxx @@ -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(); diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx index 2fbf657b5f..69ebdab43d 100644 --- a/Source/cmWorkerPool.cxx +++ b/Source/cmWorkerPool.cxx @@ -250,6 +250,9 @@ bool cmUVReadOnlyProcess::start(uv_loop_t* uv_loop, this->UVOptions_.args = const_cast(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(this->UVOptionsStdIO_.size()); this->UVOptions_.stdio = this->UVOptionsStdIO_.data(); diff --git a/Tests/CMakeLib/testUVStreambuf.cxx b/Tests/CMakeLib/testUVStreambuf.cxx index af06a8ec5a..1f42727f04 100644 --- a/Tests/CMakeLib/testUVStreambuf.cxx +++ b/Tests/CMakeLib/testUVStreambuf.cxx @@ -106,6 +106,9 @@ static bool writeDataToStreamProcess(uv_loop_t& loop, options.file = cmakeCommand; options.args = const_cast(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(stdio.size()); options.exit_cb = [](uv_process_t* handle, int64_t exitStatus, diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h index 42e34467ef..94113d11b7 100644 --- a/Utilities/cmlibuv/include/uv.h +++ b/Utilities/cmlibuv/include/uv.h @@ -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) }; /* diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c index ebe185d687..729a44b472 100644 --- a/Utilities/cmlibuv/src/unix/process.c +++ b/Utilities/cmlibuv/src/unix/process.c @@ -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); diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c index 5cf9fb8066..59db8f81ac 100644 --- a/Utilities/cmlibuv/src/win/process.c +++ b/Utilities/cmlibuv/src/win/process.c @@ -90,7 +90,6 @@ static void uv__init_global_job_handle(void) { info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK | - JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; uv_global_job_handle_ = CreateJobObjectW(&attr, NULL); @@ -993,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,7 +1097,10 @@ int uv_spawn(uv_loop_t* loop, startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1); startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2); - process_flags = CREATE_UNICODE_ENVIRONMENT; + 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)) {