Просмотр исходного кода

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
Dylan Snelgrove 1 год назад
Родитель
Сommit
0f515c2d26

+ 3 - 0
Source/CTest/cmProcess.cxx

@@ -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);

+ 3 - 0
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();

+ 3 - 0
Source/cmWorkerPool.cxx

@@ -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();

+ 3 - 0
Tests/CMakeLib/testUVStreambuf.cxx

@@ -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,

+ 7 - 1
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)
 };
 
 /*

+ 2 - 1
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);

+ 5 - 1
Utilities/cmlibuv/src/win/process.c

@@ -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)) {