| 336 | } |
| 337 | |
| 338 | void cmUVProcessChain::InternalData::SpawnProcess( |
| 339 | std::size_t index, |
| 340 | cmUVProcessChainBuilder::ProcessConfiguration const& config, bool first, |
| 341 | bool last) |
| 342 | { |
| 343 | auto& process = *this->Processes[index]; |
| 344 | |
| 345 | auto options = uv_process_options_t(); |
| 346 | |
| 347 | // Bounds were checked at add time, first element is guaranteed to exist |
| 348 | options.file = config.Arguments[0].c_str(); |
| 349 | |
| 350 | std::vector<char const*> arguments; |
| 351 | arguments.reserve(config.Arguments.size()); |
| 352 | for (auto const& arg : config.Arguments) { |
| 353 | arguments.push_back(arg.c_str()); |
| 354 | } |
| 355 | arguments.push_back(nullptr); |
| 356 | options.args = const_cast<char**>(arguments.data()); |
| 357 | options.flags = UV_PROCESS_WINDOWS_HIDE; |
| 358 | if (this->Builder->Detached) { |
| 359 | options.flags |= UV_PROCESS_DETACHED; |
| 360 | } |
| 361 | #if UV_VERSION_MAJOR > 1 || \ |
| 362 | (UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 48) || \ |
| 363 | !defined(CMAKE_USE_SYSTEM_LIBUV) |
| 364 | options.flags |= UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME; |
| 365 | #endif |
| 366 | #if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV) |
| 367 | options.flags |= UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE; |
| 368 | #endif |
| 369 | if (!this->Builder->WorkingDirectory.empty()) { |
| 370 | options.cwd = this->Builder->WorkingDirectory.c_str(); |
| 371 | } |
| 372 | |
| 373 | std::array<uv_stdio_container_t, 3> stdio; |
| 374 | if (first) { |
| 375 | stdio[0] = this->InputStreamData.Stdio; |
| 376 | } else { |
| 377 | stdio[0] = uv_stdio_container_t(); |
| 378 | stdio[0].flags = UV_INHERIT_STREAM; |
| 379 | stdio[0].data.stream = process.InputPipe; |
| 380 | } |
| 381 | if (last) { |
| 382 | stdio[1] = this->OutputStreamData.Stdio; |
| 383 | } else { |
| 384 | stdio[1] = uv_stdio_container_t(); |
| 385 | stdio[1].flags = UV_INHERIT_STREAM; |
| 386 | stdio[1].data.stream = process.OutputPipe; |
| 387 | } |
| 388 | stdio[2] = this->ErrorStreamData.Stdio; |
| 389 | |
| 390 | options.stdio = stdio.data(); |
| 391 | options.stdio_count = 3; |
| 392 | options.exit_cb = [](uv_process_t* handle, int64_t exitStatus, |
| 393 | int termSignal) { |
| 394 | auto* processData = static_cast<ProcessData*>(handle->data); |
| 395 | processData->ProcessStatus.ExitStatus = exitStatus; |