/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmUVProcessChain.h"

#include <array>
#include <csignal>
#include <cstdio>
#include <istream> // IWYU pragma: keep
#include <utility>

#include <cm/memory>

#include <cm3p/uv.h>

#include "cmsys/Process.h"

#include "cm_fileno.hxx"

#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"

struct cmUVProcessChain::InternalData
{
  struct StreamData
  {
    cm::uv_pipe_ptr BuiltinStream;
    uv_stdio_container_t Stdio;
  };

  struct ProcessData
  {
    cmUVProcessChain::InternalData* Data;
    cm::uv_process_ptr Process;
    cm::uv_pipe_ptr InputPipe;
    cm::uv_pipe_ptr OutputPipe;
    Status ProcessStatus;

    void Finish();
  };

  cmUVProcessChainBuilder const* Builder = nullptr;

  bool Valid = false;

  cm::uv_loop_ptr BuiltinLoop;
  uv_loop_t* Loop;

  StreamData InputStreamData;
  StreamData OutputStreamData;
  StreamData ErrorStreamData;
  cm::uv_pipe_ptr TempOutputPipe;
  cm::uv_pipe_ptr TempErrorPipe;

  unsigned int ProcessesCompleted = 0;
  std::vector<std::unique_ptr<ProcessData>> Processes;

  bool Prepare(cmUVProcessChainBuilder const* builder);
  void SpawnProcess(
    std::size_t index,
    cmUVProcessChainBuilder::ProcessConfiguration const& config, bool first,
    bool last);
  void Finish();
  void Terminate();
};

cmUVProcessChainBuilder::cmUVProcessChainBuilder() = default;

cmUVProcessChainBuilder& cmUVProcessChainBuilder::AddCommand(
  std::vector<std::string> arguments)
{
  if (!arguments.empty()) {
    this->Processes.emplace_back();
    this->Processes.back().Arguments = std::move(arguments);
  }
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetBuiltinLoop()
{
  this->Loop = nullptr;
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetExternalLoop(
  uv_loop_t& loop)
{
  this->Loop = &loop;
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetNoStream(Stream stdio)
{
  switch (stdio) {
    case Stream_INPUT:
    case Stream_OUTPUT:
    case Stream_ERROR: {
      auto& streamData = this->Stdio[stdio];
      streamData.Type = None;
      break;
    }
  }
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetBuiltinStream(
  Stream stdio)
{
  switch (stdio) {
    case Stream_INPUT:
      // FIXME
      break;

    case Stream_OUTPUT:
    case Stream_ERROR: {
      auto& streamData = this->Stdio[stdio];
      streamData.Type = Builtin;
      break;
    }
  }
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetExternalStream(
  Stream stdio, int fd)
{
  switch (stdio) {
    case Stream_INPUT:
    case Stream_OUTPUT:
    case Stream_ERROR: {
      auto& streamData = this->Stdio[stdio];
      streamData.Type = External;
      streamData.FileDescriptor = fd;
      break;
    }
  }
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetExternalStream(
  Stream stdio, FILE* stream)
{
  int fd = cm_fileno(stream);
  if (fd >= 0) {
    return this->SetExternalStream(stdio, fd);
  }
  return this->SetNoStream(stdio);
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetMergedBuiltinStreams()
{
  this->MergedBuiltinStreams = true;
  return this->SetBuiltinStream(Stream_OUTPUT).SetBuiltinStream(Stream_ERROR);
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetWorkingDirectory(
  std::string dir)
{
  this->WorkingDirectory = std::move(dir);
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetEnvironment(
  std::vector<std::string> env)
{
  this->Environment = std::move(env);
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetDetached()
{
  this->Detached = true;
  return *this;
}

uv_loop_t* cmUVProcessChainBuilder::GetLoop() const
{
  return this->Loop;
}

cmUVProcessChain cmUVProcessChainBuilder::Start() const
{
  cmUVProcessChain chain;

  if (!chain.Data->Prepare(this)) {
    return chain;
  }

  for (std::size_t i = 0; i < this->Processes.size(); i++) {
    chain.Data->SpawnProcess(i, this->Processes[i], i == 0,
                             i == this->Processes.size() - 1);
  }

  chain.Data->Finish();

  return chain;
}

bool cmUVProcessChain::InternalData::Prepare(
  cmUVProcessChainBuilder const* builder)
{
  this->Builder = builder;

  if (this->Builder->Loop) {
    this->Loop = this->Builder->Loop;
  } else {
    this->BuiltinLoop.init();
    this->Loop = this->BuiltinLoop;
  }

  auto const& input =
    this->Builder->Stdio[cmUVProcessChainBuilder::Stream_INPUT];
  auto& inputData = this->InputStreamData;
  switch (input.Type) {
    case cmUVProcessChainBuilder::None:
      inputData.Stdio.flags = UV_IGNORE;
      break;

    case cmUVProcessChainBuilder::Builtin: {
      // FIXME
      break;
    }

    case cmUVProcessChainBuilder::External:
      inputData.Stdio.flags = UV_INHERIT_FD;
      inputData.Stdio.data.fd = input.FileDescriptor;
      break;
  }

  auto const& output =
    this->Builder->Stdio[cmUVProcessChainBuilder::Stream_OUTPUT];
  auto& outputData = this->OutputStreamData;
  switch (output.Type) {
    case cmUVProcessChainBuilder::None:
      outputData.Stdio.flags = UV_IGNORE;
      break;

    case cmUVProcessChainBuilder::Builtin: {
      int pipeFd[2];
      if (cmGetPipes(pipeFd) < 0) {
        return false;
      }

      if (outputData.BuiltinStream.init(*this->Loop, 0) < 0) {
        return false;
      }
      if (uv_pipe_open(outputData.BuiltinStream, pipeFd[0]) < 0) {
        return false;
      }

      if (this->TempOutputPipe.init(*this->Loop, 0) < 0) {
        return false;
      }
      if (uv_pipe_open(this->TempOutputPipe, pipeFd[1]) < 0) {
        return false;
      }

      outputData.Stdio.flags = UV_INHERIT_FD;
      outputData.Stdio.data.fd = pipeFd[1];
    } break;

    case cmUVProcessChainBuilder::External:
      outputData.Stdio.flags = UV_INHERIT_FD;
      outputData.Stdio.data.fd = output.FileDescriptor;
      break;
  }

  auto const& error =
    this->Builder->Stdio[cmUVProcessChainBuilder::Stream_ERROR];
  auto& errorData = this->ErrorStreamData;
  switch (error.Type) {
    case cmUVProcessChainBuilder::None:
      errorData.Stdio.flags = UV_IGNORE;
      break;

    case cmUVProcessChainBuilder::Builtin: {
      if (this->Builder->MergedBuiltinStreams) {
        errorData.Stdio.flags = UV_INHERIT_FD;
        errorData.Stdio.data.fd = outputData.Stdio.data.fd;
      } else {
        int pipeFd[2];
        if (cmGetPipes(pipeFd) < 0) {
          return false;
        }

        if (errorData.BuiltinStream.init(*this->Loop, 0) < 0) {
          return false;
        }
        if (uv_pipe_open(errorData.BuiltinStream, pipeFd[0]) < 0) {
          return false;
        }

        if (this->TempErrorPipe.init(*this->Loop, 0) < 0) {
          return false;
        }
        if (uv_pipe_open(this->TempErrorPipe, pipeFd[1]) < 0) {
          return false;
        }

        errorData.Stdio.flags = UV_INHERIT_FD;
        errorData.Stdio.data.fd = pipeFd[1];
      }
    } break;

    case cmUVProcessChainBuilder::External:
      errorData.Stdio.flags = UV_INHERIT_FD;
      errorData.Stdio.data.fd = error.FileDescriptor;
      break;
  }

  bool first = true;
  for (std::size_t i = 0; i < this->Builder->Processes.size(); i++) {
    this->Processes.emplace_back(cm::make_unique<ProcessData>());
    auto& process = *this->Processes.back();
    process.Data = this;
    process.ProcessStatus.Finished = false;

    if (!first) {
      auto& prevProcess = *this->Processes[i - 1];

      int pipeFd[2];
      if (cmGetPipes(pipeFd) < 0) {
        return false;
      }

      if (prevProcess.OutputPipe.init(*this->Loop, 0) < 0) {
        return false;
      }
      if (uv_pipe_open(prevProcess.OutputPipe, pipeFd[1]) < 0) {
        return false;
      }
      if (process.InputPipe.init(*this->Loop, 0) < 0) {
        return false;
      }
      if (uv_pipe_open(process.InputPipe, pipeFd[0]) < 0) {
        return false;
      }
    }

    first = false;
  }

  return true;
}

void cmUVProcessChain::InternalData::SpawnProcess(
  std::size_t index,
  cmUVProcessChainBuilder::ProcessConfiguration const& config, bool first,
  bool last)
{
  auto& process = *this->Processes[index];

  auto options = uv_process_options_t();

  // Bounds were checked at add time, first element is guaranteed to exist
  options.file = config.Arguments[0].c_str();

  std::vector<char const*> arguments;
  arguments.reserve(config.Arguments.size());
  for (auto const& arg : config.Arguments) {
    arguments.push_back(arg.c_str());
  }
  arguments.push_back(nullptr);
  options.args = const_cast<char**>(arguments.data());
  options.flags = UV_PROCESS_WINDOWS_HIDE;
  if (this->Builder->Detached) {
    options.flags |= UV_PROCESS_DETACHED;
  }
#if UV_VERSION_MAJOR > 1 ||                                                   \
  (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();
  }

  auto env = std::vector<char const*>{};
  if (!this->Builder->Environment.empty()) {
    env.reserve(this->Builder->Environment.size() + 1);
    for (auto const& var : this->Builder->Environment) {
      env.push_back(var.c_str());
    }
    env.push_back(nullptr);
    options.env = const_cast<char**>(env.data());
  }

  std::array<uv_stdio_container_t, 3> stdio;
  if (first) {
    stdio[0] = this->InputStreamData.Stdio;
  } else {
    stdio[0] = uv_stdio_container_t();
    stdio[0].flags = UV_INHERIT_STREAM;
    stdio[0].data.stream = process.InputPipe;
  }
  if (last) {
    stdio[1] = this->OutputStreamData.Stdio;
  } else {
    stdio[1] = uv_stdio_container_t();
    stdio[1].flags = UV_INHERIT_STREAM;
    stdio[1].data.stream = process.OutputPipe;
  }
  stdio[2] = this->ErrorStreamData.Stdio;

  options.stdio = stdio.data();
  options.stdio_count = 3;
  options.exit_cb = [](uv_process_t* handle, int64_t exitStatus,
                       int termSignal) {
    auto* processData = static_cast<ProcessData*>(handle->data);
    processData->ProcessStatus.ExitStatus = exitStatus;
    processData->ProcessStatus.TermSignal = termSignal;
    processData->Finish();
  };

  if ((process.ProcessStatus.SpawnResult =
         process.Process.spawn(*this->Loop, options, &process)) < 0) {
    process.Finish();
  }
  if (this->Builder->Detached) {
    uv_unref((uv_handle_t*)process.Process);
  }
  process.InputPipe.reset();
  process.OutputPipe.reset();
}

void cmUVProcessChain::InternalData::Finish()
{
  this->TempOutputPipe.reset();
  this->TempErrorPipe.reset();
  this->Valid = true;
}

void cmUVProcessChain::InternalData::Terminate()
{
  for (std::unique_ptr<ProcessData> const& p : this->Processes) {
    if (!p->ProcessStatus.Finished) {
      cmsysProcess_KillPID(static_cast<unsigned long>(p->Process->pid));
    }
  }
}

cmUVProcessChain::cmUVProcessChain()
  : Data(cm::make_unique<InternalData>())
{
}

cmUVProcessChain::cmUVProcessChain(cmUVProcessChain&& other) noexcept
  : Data(std::move(other.Data))
{
}

cmUVProcessChain::~cmUVProcessChain() = default;

cmUVProcessChain& cmUVProcessChain::operator=(
  cmUVProcessChain&& other) noexcept
{
  this->Data = std::move(other.Data);
  return *this;
}

uv_loop_t& cmUVProcessChain::GetLoop()
{
  return *this->Data->Loop;
}

uv_stream_t* cmUVProcessChain::OutputStream()
{
  return this->Data->OutputStreamData.BuiltinStream;
}

uv_stream_t* cmUVProcessChain::ErrorStream()
{
  return this->Data->ErrorStreamData.BuiltinStream;
}

bool cmUVProcessChain::Valid() const
{
  return this->Data->Valid;
}

bool cmUVProcessChain::Wait(uint64_t milliseconds)
{
  bool timeout = false;
  cm::uv_timer_ptr timer;

  if (milliseconds > 0) {
    timer.init(*this->Data->Loop, &timeout);
    timer.start(
      [](uv_timer_t* handle) {
        auto* timeoutPtr = static_cast<bool*>(handle->data);
        *timeoutPtr = true;
      },
      milliseconds, 0, cm::uv_update_time::yes);
  }

  while (!timeout &&
         this->Data->ProcessesCompleted < this->Data->Processes.size()) {
    uv_run(this->Data->Loop, UV_RUN_ONCE);
  }

  return !timeout;
}

std::vector<cmUVProcessChain::Status const*> cmUVProcessChain::GetStatus()
  const
{
  std::vector<cmUVProcessChain::Status const*> statuses(
    this->Data->Processes.size(), nullptr);
  for (std::size_t i = 0; i < statuses.size(); i++) {
    statuses[i] = &this->GetStatus(i);
  }
  return statuses;
}

cmUVProcessChain::Status const& cmUVProcessChain::GetStatus(
  std::size_t index) const
{
  return this->Data->Processes[index]->ProcessStatus;
}

bool cmUVProcessChain::Finished() const
{
  return this->Data->ProcessesCompleted >= this->Data->Processes.size();
}

void cmUVProcessChain::Terminate()
{
  this->Data->Terminate();
}

std::pair<cmUVProcessChain::ExceptionCode, std::string>
cmUVProcessChain::Status::GetException() const
{
  if (this->SpawnResult) {
    return std::make_pair(ExceptionCode::Spawn,
                          uv_strerror(this->SpawnResult));
  }
#ifdef _WIN32
  if (this->Finished && (this->ExitStatus & 0xF0000000) == 0xC0000000) {
    // Child terminated due to exceptional behavior.
    switch (this->ExitStatus) {
      case STATUS_CONTROL_C_EXIT:
        return std::make_pair(ExceptionCode::Interrupt, "User interrupt");

      case STATUS_FLOAT_DENORMAL_OPERAND:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception (denormal operand)");
      case STATUS_FLOAT_DIVIDE_BY_ZERO:
        return std::make_pair(ExceptionCode::Numerical, "Divide-by-zero");
      case STATUS_FLOAT_INEXACT_RESULT:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception (inexact result)");
      case STATUS_FLOAT_INVALID_OPERATION:
        return std::make_pair(ExceptionCode::Numerical,
                              "Invalid floating-point operation");
      case STATUS_FLOAT_OVERFLOW:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point overflow");
      case STATUS_FLOAT_STACK_CHECK:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point stack check failed");
      case STATUS_FLOAT_UNDERFLOW:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point underflow");
#  ifdef STATUS_FLOAT_MULTIPLE_FAULTS
      case STATUS_FLOAT_MULTIPLE_FAULTS:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception (multiple faults)");
#  endif
#  ifdef STATUS_FLOAT_MULTIPLE_TRAPS
      case STATUS_FLOAT_MULTIPLE_TRAPS:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception (multiple traps)");
#  endif
      case STATUS_INTEGER_DIVIDE_BY_ZERO:
        return std::make_pair(ExceptionCode::Numerical,
                              "Integer divide-by-zero");
      case STATUS_INTEGER_OVERFLOW:
        return std::make_pair(ExceptionCode::Numerical, "Integer overflow");

      case STATUS_DATATYPE_MISALIGNMENT:
        return std::make_pair(ExceptionCode::Fault, "Datatype misalignment");
      case STATUS_ACCESS_VIOLATION:
        return std::make_pair(ExceptionCode::Fault, "Access violation");
      case STATUS_IN_PAGE_ERROR:
        return std::make_pair(ExceptionCode::Fault, "In-page error");
      case STATUS_INVALID_HANDLE:
        return std::make_pair(ExceptionCode::Fault, "Invalid handle");
      case STATUS_NONCONTINUABLE_EXCEPTION:
        return std::make_pair(ExceptionCode::Fault,
                              "Noncontinuable exception");
      case STATUS_INVALID_DISPOSITION:
        return std::make_pair(ExceptionCode::Fault, "Invalid disposition");
      case STATUS_ARRAY_BOUNDS_EXCEEDED:
        return std::make_pair(ExceptionCode::Fault, "Array bounds exceeded");
      case STATUS_STACK_OVERFLOW:
        return std::make_pair(ExceptionCode::Fault, "Stack overflow");

      case STATUS_ILLEGAL_INSTRUCTION:
        return std::make_pair(ExceptionCode::Illegal, "Illegal instruction");
      case STATUS_PRIVILEGED_INSTRUCTION:
        return std::make_pair(ExceptionCode::Illegal,
                              "Privileged instruction");

      case STATUS_NO_MEMORY:
      default: {
        char buf[256];
        snprintf(buf, sizeof(buf), "Exit code 0x%x",
                 static_cast<unsigned int>(this->ExitStatus));
        return std::make_pair(ExceptionCode::Other, buf);
      }
    }
  }
#else
  if (this->Finished && this->TermSignal) {
    switch (this->TermSignal) {
#  ifdef SIGSEGV
      case SIGSEGV:
        return std::make_pair(ExceptionCode::Fault, "Segmentation fault");
#  endif
#  ifdef SIGBUS
#    if !defined(SIGSEGV) || SIGBUS != SIGSEGV
      case SIGBUS:
        return std::make_pair(ExceptionCode::Fault, "Bus error");
#    endif
#  endif
#  ifdef SIGFPE
      case SIGFPE:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception");
#  endif
#  ifdef SIGILL
      case SIGILL:
        return std::make_pair(ExceptionCode::Illegal, "Illegal instruction");
#  endif
#  ifdef SIGINT
      case SIGINT:
        return std::make_pair(ExceptionCode::Interrupt, "User interrupt");
#  endif
#  ifdef SIGABRT
      case SIGABRT:
        return std::make_pair(ExceptionCode::Other, "Subprocess aborted");
#  endif
#  ifdef SIGKILL
      case SIGKILL:
        return std::make_pair(ExceptionCode::Other, "Subprocess killed");
#  endif
#  ifdef SIGTERM
      case SIGTERM:
        return std::make_pair(ExceptionCode::Other, "Subprocess terminated");
#  endif
#  ifdef SIGHUP
      case SIGHUP:
        return std::make_pair(ExceptionCode::Other, "SIGHUP");
#  endif
#  ifdef SIGQUIT
      case SIGQUIT:
        return std::make_pair(ExceptionCode::Other, "SIGQUIT");
#  endif
#  ifdef SIGTRAP
      case SIGTRAP:
        return std::make_pair(ExceptionCode::Other, "SIGTRAP");
#  endif
#  ifdef SIGIOT
#    if !defined(SIGABRT) || SIGIOT != SIGABRT
      case SIGIOT:
        return std::make_pair(ExceptionCode::Other, "SIGIOT");
#    endif
#  endif
#  ifdef SIGUSR1
      case SIGUSR1:
        return std::make_pair(ExceptionCode::Other, "SIGUSR1");
#  endif
#  ifdef SIGUSR2
      case SIGUSR2:
        return std::make_pair(ExceptionCode::Other, "SIGUSR2");
#  endif
#  ifdef SIGPIPE
      case SIGPIPE:
        return std::make_pair(ExceptionCode::Other, "SIGPIPE");
#  endif
#  ifdef SIGALRM
      case SIGALRM:
        return std::make_pair(ExceptionCode::Other, "SIGALRM");
#  endif
#  ifdef SIGSTKFLT
      case SIGSTKFLT:
        return std::make_pair(ExceptionCode::Other, "SIGSTKFLT");
#  endif
#  ifdef SIGCHLD
      case SIGCHLD:
        return std::make_pair(ExceptionCode::Other, "SIGCHLD");
#  elif defined(SIGCLD)
      case SIGCLD:
        return std::make_pair(ExceptionCode::Other, "SIGCLD");
#  endif
#  ifdef SIGCONT
      case SIGCONT:
        return std::make_pair(ExceptionCode::Other, "SIGCONT");
#  endif
#  ifdef SIGSTOP
      case SIGSTOP:
        return std::make_pair(ExceptionCode::Other, "SIGSTOP");
#  endif
#  ifdef SIGTSTP
      case SIGTSTP:
        return std::make_pair(ExceptionCode::Other, "SIGTSTP");
#  endif
#  ifdef SIGTTIN
      case SIGTTIN:
        return std::make_pair(ExceptionCode::Other, "SIGTTIN");
#  endif
#  ifdef SIGTTOU
      case SIGTTOU:
        return std::make_pair(ExceptionCode::Other, "SIGTTOU");
#  endif
#  ifdef SIGURG
      case SIGURG:
        return std::make_pair(ExceptionCode::Other, "SIGURG");
#  endif
#  ifdef SIGXCPU
      case SIGXCPU:
        return std::make_pair(ExceptionCode::Other, "SIGXCPU");
#  endif
#  ifdef SIGXFSZ
      case SIGXFSZ:
        return std::make_pair(ExceptionCode::Other, "SIGXFSZ");
#  endif
#  ifdef SIGVTALRM
      case SIGVTALRM:
        return std::make_pair(ExceptionCode::Other, "SIGVTALRM");
#  endif
#  ifdef SIGPROF
      case SIGPROF:
        return std::make_pair(ExceptionCode::Other, "SIGPROF");
#  endif
#  ifdef SIGWINCH
      case SIGWINCH:
        return std::make_pair(ExceptionCode::Other, "SIGWINCH");
#  endif
#  ifdef SIGPOLL
      case SIGPOLL:
        return std::make_pair(ExceptionCode::Other, "SIGPOLL");
#  endif
#  ifdef SIGIO
#    if !defined(SIGPOLL) || SIGIO != SIGPOLL
      case SIGIO:
        return std::make_pair(ExceptionCode::Other, "SIGIO");
#    endif
#  endif
#  ifdef SIGPWR
      case SIGPWR:
        return std::make_pair(ExceptionCode::Other, "SIGPWR");
#  endif
#  ifdef SIGSYS
      case SIGSYS:
        return std::make_pair(ExceptionCode::Other, "SIGSYS");
#  endif
#  ifdef SIGUNUSED
#    if !defined(SIGSYS) || SIGUNUSED != SIGSYS
      case SIGUNUSED:
        return std::make_pair(ExceptionCode::Other, "SIGUNUSED");
#    endif
#  endif
      default: {
        char buf[256];
        snprintf(buf, sizeof(buf), "Signal %d", this->TermSignal);
        return std::make_pair(ExceptionCode::Other, buf);
      }
    }
  }
#endif
  return std::make_pair(ExceptionCode::None, "");
}

void cmUVProcessChain::InternalData::ProcessData::Finish()
{
  this->ProcessStatus.Finished = true;
  this->Data->ProcessesCompleted++;
}
