/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Process.h)
#include KWSYS_HEADER(Encoding.h)

/* Work-around CMake dependency scanning limitation.  This must
   duplicate the above list of headers.  */
#if 0
#  include "Encoding.h.in"
#  include "Process.h.in"
#endif

/*

Implementation for Windows

On windows, a thread is created to wait for data on each pipe.  The
threads are synchronized with the main thread to simulate the use of
a UNIX-style select system call.

*/

#ifdef _MSC_VER
#  pragma warning(push, 1)
#endif
#include <windows.h> /* Windows API */
#if defined(_MSC_VER) && _MSC_VER >= 1800
#  define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
#endif
#include <io.h>     /* _unlink */
#include <stdio.h>  /* snprintf */
#include <string.h> /* strlen, strdup */

#ifndef _MAX_FNAME
#  define _MAX_FNAME 4096
#endif
#ifndef _MAX_PATH
#  define _MAX_PATH 4096
#endif

#ifdef _MSC_VER
#  pragma warning(pop)
#  pragma warning(disable : 4514)
#  pragma warning(disable : 4706)
#endif

/* There are pipes for the process pipeline's stdout and stderr.  */
#define KWSYSPE_PIPE_COUNT 2
#define KWSYSPE_PIPE_STDOUT 0
#define KWSYSPE_PIPE_STDERR 1

/* The maximum amount to read from a pipe at a time.  */
#define KWSYSPE_PIPE_BUFFER_SIZE 1024

/* Debug output macro.  */
#if 0
#  define KWSYSPE_DEBUG(x)                                                    \
    ((void*)cp == (void*)0x00226DE0                                           \
       ? (fprintf(stderr, "%d/%p/%d ", (int)GetCurrentProcessId(), cp,        \
                  __LINE__),                                                  \
          fprintf x, fflush(stderr), 1)                                       \
       : (1))
#else
#  define KWSYSPE_DEBUG(x) (void)1
#endif

typedef LARGE_INTEGER kwsysProcessTime;

typedef struct kwsysProcessCreateInformation_s
{
  /* Windows child startup control data.  */
  STARTUPINFOW StartupInfo;

  /* Original handles before making inherited duplicates.  */
  HANDLE hStdInput;
  HANDLE hStdOutput;
  HANDLE hStdError;
} kwsysProcessCreateInformation;

typedef struct kwsysProcessPipeData_s kwsysProcessPipeData;
static DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd);
static void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp,
                                           kwsysProcessPipeData* td);
static DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd);
static void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp,
                                           kwsysProcessPipeData* td);
static int kwsysProcessInitialize(kwsysProcess* cp);
static DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
                                kwsysProcessCreateInformation* si);
static void kwsysProcessDestroy(kwsysProcess* cp, int event);
static DWORD kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name);
static void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle);
static void kwsysProcessCleanupHandle(PHANDLE h);
static void kwsysProcessCleanup(kwsysProcess* cp, DWORD error);
static void kwsysProcessCleanErrorMessage(kwsysProcess* cp);
static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
                                      kwsysProcessTime* timeoutTime);
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
                                      double* userTimeout,
                                      kwsysProcessTime* timeoutLength);
static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
static DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t);
static double kwsysProcessTimeToDouble(kwsysProcessTime t);
static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1,
                                            kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1,
                                                 kwsysProcessTime in2);
static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int code,
                                                int idx);
static void kwsysProcessKillTree(int pid);
static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
static int kwsysProcessesInitialize(void);
static int kwsysTryEnterCreateProcessSection(void);
static void kwsysLeaveCreateProcessSection(void);
static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessId,
                             int newProcessGroup);
static void kwsysProcessesRemove(HANDLE hProcess);
static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType);

/* A structure containing synchronization data for each thread.  */
typedef struct kwsysProcessPipeSync_s kwsysProcessPipeSync;
struct kwsysProcessPipeSync_s
{
  /* Handle to the thread.  */
  HANDLE Thread;

  /* Semaphore indicating to the thread that a process has started.  */
  HANDLE Ready;

  /* Semaphore indicating to the thread that it should begin work.  */
  HANDLE Go;

  /* Semaphore indicating thread has reset for another process.  */
  HANDLE Reset;
};

/* A structure containing data for each pipe's threads.  */
struct kwsysProcessPipeData_s
{
  /* ------------- Data managed per instance of kwsysProcess ------------- */

  /* Synchronization data for reading thread.  */
  kwsysProcessPipeSync Reader;

  /* Synchronization data for waking thread.  */
  kwsysProcessPipeSync Waker;

  /* Index of this pipe.  */
  int Index;

  /* The kwsysProcess instance owning this pipe.  */
  kwsysProcess* Process;

  /* ------------- Data managed per call to Execute ------------- */

  /* Buffer for data read in this pipe's thread.  */
  char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE];

  /* The length of the data stored in the buffer.  */
  DWORD DataLength;

  /* Whether the pipe has been closed.  */
  int Closed;

  /* Handle for the read end of this pipe. */
  HANDLE Read;

  /* Handle for the write end of this pipe. */
  HANDLE Write;
};

/* A structure containing results data for each process.  */
typedef struct kwsysProcessResults_s kwsysProcessResults;
struct kwsysProcessResults_s
{
  /* The status of the process.  */
  int State;

  /* The exceptional behavior that terminated the process, if any.  */
  int ExitException;

  /* The process exit code.  */
  DWORD ExitCode;

  /* The process return code, if any.  */
  int ExitValue;

  /* Description for the ExitException.  */
  char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE + 1];
};

/* Structure containing data used to implement the child's execution.  */
struct kwsysProcess_s
{
  /* ------------- Data managed per instance of kwsysProcess ------------- */

  /* The status of the process structure.  */
  int State;

  /* The command lines to execute.  */
  wchar_t** Commands;
  int NumberOfCommands;

  /* The exit code of each command.  */
  DWORD* CommandExitCodes;

  /* The working directory for the child process.  */
  wchar_t* WorkingDirectory;

  /* Whether to create the child as a detached process.  */
  int OptionDetach;

  /* Whether the child was created as a detached process.  */
  int Detached;

  /* Whether to hide the child process's window.  */
  int HideWindow;

  /* Whether to treat command lines as verbatim.  */
  int Verbatim;

  /* Whether to merge stdout/stderr of the child.  */
  int MergeOutput;

  /* Whether to create the process in a new process group.  */
  int CreateProcessGroup;

  /* Mutex to protect the shared index used by threads to report data.  */
  HANDLE SharedIndexMutex;

  /* Semaphore used by threads to signal data ready.  */
  HANDLE Full;

  /* Whether we are currently deleting this kwsysProcess instance.  */
  int Deleting;

  /* Data specific to each pipe and its thread.  */
  kwsysProcessPipeData Pipe[KWSYSPE_PIPE_COUNT];

  /* Name of files to which stdin and stdout pipes are attached.  */
  char* PipeFileSTDIN;
  char* PipeFileSTDOUT;
  char* PipeFileSTDERR;

  /* Whether each pipe is shared with the parent process.  */
  int PipeSharedSTDIN;
  int PipeSharedSTDOUT;
  int PipeSharedSTDERR;

  /* Native pipes provided by the user.  */
  HANDLE PipeNativeSTDIN[2];
  HANDLE PipeNativeSTDOUT[2];
  HANDLE PipeNativeSTDERR[2];

  /* ------------- Data managed per call to Execute ------------- */

  /* Index of last pipe to report data, if any.  */
  int CurrentIndex;

  /* Index shared by threads to report data.  */
  int SharedIndex;

  /* The timeout length.  */
  double Timeout;

  /* Time at which the child started.  */
  kwsysProcessTime StartTime;

  /* Time at which the child will timeout.  Negative for no timeout.  */
  kwsysProcessTime TimeoutTime;

  /* Flag for whether the process was killed.  */
  int Killed;

  /* Flag for whether the timeout expired.  */
  int TimeoutExpired;

  /* Flag for whether the process has terminated.  */
  int Terminated;

  /* The number of pipes still open during execution and while waiting
     for pipes to close after process termination.  */
  int PipesLeft;

  /* Buffer for error messages.  */
  char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE + 1];

  /* process results.  */
  kwsysProcessResults* ProcessResults;

  /* Windows process information data.  */
  PROCESS_INFORMATION* ProcessInformation;

  /* Data and process termination events for which to wait.  */
  PHANDLE ProcessEvents;
  int ProcessEventsLength;

  /* Real working directory of our own process.  */
  DWORD RealWorkingDirectoryLength;
  wchar_t* RealWorkingDirectory;

  /* Own handles for the child's ends of the pipes in the parent process.
     Used temporarily during process creation.  */
  HANDLE PipeChildStd[3];
};

kwsysProcess* kwsysProcess_New(void)
{
  int i;

  /* Process control structure.  */
  kwsysProcess* cp;

  /* Windows version number data.  */
  OSVERSIONINFO osv;

  /* Initialize list of processes before we get any farther.  It's especially
     important that the console Ctrl handler be added BEFORE starting the
     first process.  This prevents the risk of an orphaned process being
     started by the main thread while the default Ctrl handler is in
     progress.  */
  if (!kwsysProcessesInitialize()) {
    return 0;
  }

  /* Allocate a process control structure.  */
  cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
  if (!cp) {
    /* Could not allocate memory for the control structure.  */
    return 0;
  }
  ZeroMemory(cp, sizeof(*cp));

  /* Share stdin with the parent process by default.  */
  cp->PipeSharedSTDIN = 1;

  /* Set initial status.  */
  cp->State = kwsysProcess_State_Starting;

  /* Choose a method of running the child based on version of
     windows.  */
  ZeroMemory(&osv, sizeof(osv));
  osv.dwOSVersionInfoSize = sizeof(osv);
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
#  pragma warning(push)
#  ifdef __INTEL_COMPILER
#    pragma warning(disable : 1478)
#  elif defined __clang__
#    pragma clang diagnostic push
#    pragma clang diagnostic ignored "-Wdeprecated-declarations"
#  else
#    pragma warning(disable : 4996)
#  endif
#endif
  GetVersionEx(&osv);
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
#  ifdef __clang__
#    pragma clang diagnostic pop
#  else
#    pragma warning(pop)
#  endif
#endif
  if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
    /* Win9x no longer supported.  */
    kwsysProcess_Delete(cp);
    return 0;
  }

  /* Initially no thread owns the mutex.  Initialize semaphore to 1.  */
  if (!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0))) {
    kwsysProcess_Delete(cp);
    return 0;
  }

  /* Initially no data are available.  Initialize semaphore to 0.  */
  if (!(cp->Full = CreateSemaphore(0, 0, 1, 0))) {
    kwsysProcess_Delete(cp);
    return 0;
  }

  /* Create the thread to read each pipe.  */
  for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
    DWORD dummy = 0;

    /* Assign the thread its index.  */
    cp->Pipe[i].Index = i;

    /* Give the thread a pointer back to the kwsysProcess instance.  */
    cp->Pipe[i].Process = cp;

    /* No process is yet running.  Initialize semaphore to 0.  */
    if (!(cp->Pipe[i].Reader.Ready = CreateSemaphore(0, 0, 1, 0))) {
      kwsysProcess_Delete(cp);
      return 0;
    }

    /* The pipe is not yet reset.  Initialize semaphore to 0.  */
    if (!(cp->Pipe[i].Reader.Reset = CreateSemaphore(0, 0, 1, 0))) {
      kwsysProcess_Delete(cp);
      return 0;
    }

    /* The thread's buffer is initially empty.  Initialize semaphore to 1.  */
    if (!(cp->Pipe[i].Reader.Go = CreateSemaphore(0, 1, 1, 0))) {
      kwsysProcess_Delete(cp);
      return 0;
    }

    /* Create the reading thread.  It will block immediately.  The
       thread will not make deeply nested calls, so we need only a
       small stack.  */
    if (!(cp->Pipe[i].Reader.Thread = CreateThread(
            0, 1024, kwsysProcessPipeThreadRead, &cp->Pipe[i], 0, &dummy))) {
      kwsysProcess_Delete(cp);
      return 0;
    }

    /* No process is yet running.  Initialize semaphore to 0.  */
    if (!(cp->Pipe[i].Waker.Ready = CreateSemaphore(0, 0, 1, 0))) {
      kwsysProcess_Delete(cp);
      return 0;
    }

    /* The pipe is not yet reset.  Initialize semaphore to 0.  */
    if (!(cp->Pipe[i].Waker.Reset = CreateSemaphore(0, 0, 1, 0))) {
      kwsysProcess_Delete(cp);
      return 0;
    }

    /* The waker should not wake immediately.  Initialize semaphore to 0.  */
    if (!(cp->Pipe[i].Waker.Go = CreateSemaphore(0, 0, 1, 0))) {
      kwsysProcess_Delete(cp);
      return 0;
    }

    /* Create the waking thread.  It will block immediately.  The
       thread will not make deeply nested calls, so we need only a
       small stack.  */
    if (!(cp->Pipe[i].Waker.Thread = CreateThread(
            0, 1024, kwsysProcessPipeThreadWake, &cp->Pipe[i], 0, &dummy))) {
      kwsysProcess_Delete(cp);
      return 0;
    }
  }
  for (i = 0; i < 3; ++i) {
    cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
  }

  return cp;
}

void kwsysProcess_Delete(kwsysProcess* cp)
{
  int i;

  /* Make sure we have an instance.  */
  if (!cp) {
    return;
  }

  /* If the process is executing, wait for it to finish.  */
  if (cp->State == kwsysProcess_State_Executing) {
    if (cp->Detached) {
      kwsysProcess_Disown(cp);
    } else {
      kwsysProcess_WaitForExit(cp, 0);
    }
  }

  /* We are deleting the kwsysProcess instance.  */
  cp->Deleting = 1;

  /* Terminate each of the threads.  */
  for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
    /* Terminate this reading thread.  */
    if (cp->Pipe[i].Reader.Thread) {
      /* Signal the thread we are ready for it.  It will terminate
         immediately since Deleting is set.  */
      ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);

      /* Wait for the thread to exit.  */
      WaitForSingleObject(cp->Pipe[i].Reader.Thread, INFINITE);

      /* Close the handle to the thread. */
      kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Thread);
    }

    /* Terminate this waking thread.  */
    if (cp->Pipe[i].Waker.Thread) {
      /* Signal the thread we are ready for it.  It will terminate
         immediately since Deleting is set.  */
      ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);

      /* Wait for the thread to exit.  */
      WaitForSingleObject(cp->Pipe[i].Waker.Thread, INFINITE);

      /* Close the handle to the thread. */
      kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Thread);
    }

    /* Cleanup the pipe's semaphores.  */
    kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Ready);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Go);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Reset);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Ready);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Go);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Reset);
  }

  /* Close the shared semaphores.  */
  kwsysProcessCleanupHandle(&cp->SharedIndexMutex);
  kwsysProcessCleanupHandle(&cp->Full);

  /* Free memory.  */
  kwsysProcess_SetCommand(cp, 0);
  kwsysProcess_SetWorkingDirectory(cp, 0);
  kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
  kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
  kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
  free(cp->CommandExitCodes);
  free(cp->ProcessResults);
  free(cp);
}

int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
{
  int i;
  if (!cp) {
    return 0;
  }
  for (i = 0; i < cp->NumberOfCommands; ++i) {
    free(cp->Commands[i]);
  }
  cp->NumberOfCommands = 0;
  if (cp->Commands) {
    free(cp->Commands);
    cp->Commands = 0;
  }
  if (command) {
    return kwsysProcess_AddCommand(cp, command);
  }
  return 1;
}

int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
{
  int newNumberOfCommands;
  wchar_t** newCommands;

  /* Make sure we have a command to add.  */
  if (!cp || !command || !*command) {
    return 0;
  }

  /* Allocate a new array for command pointers.  */
  newNumberOfCommands = cp->NumberOfCommands + 1;
  if (!(newCommands =
          (wchar_t**)malloc(sizeof(wchar_t*) * newNumberOfCommands))) {
    /* Out of memory.  */
    return 0;
  }

  /* Copy any existing commands into the new array.  */
  {
    int i;
    for (i = 0; i < cp->NumberOfCommands; ++i) {
      newCommands[i] = cp->Commands[i];
    }
  }

  if (cp->Verbatim) {
    /* Copy the verbatim command line into the buffer.  */
    newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(*command);
  } else {
    /* Encode the arguments so CommandLineToArgvW can decode
       them from the command line string in the child.  */
    char buffer[32768]; /* CreateProcess max command-line length.  */
    char* end = buffer + sizeof(buffer);
    char* out = buffer;
    char const* const* a;
    for (a = command; *a; ++a) {
      int quote = !**a; /* Quote the empty string.  */
      int slashes = 0;
      char const* c;
      if (a != command && out != end) {
        *out++ = ' ';
      }
      for (c = *a; !quote && *c; ++c) {
        quote = (*c == ' ' || *c == '\t');
      }
      if (quote && out != end) {
        *out++ = '"';
      }
      for (c = *a; *c; ++c) {
        if (*c == '\\') {
          ++slashes;
        } else {
          if (*c == '"') {
            // Add n+1 backslashes to total 2n+1 before internal '"'.
            while (slashes-- >= 0 && out != end) {
              *out++ = '\\';
            }
          }
          slashes = 0;
        }
        if (out != end) {
          *out++ = *c;
        }
      }
      if (quote) {
        // Add n backslashes to total 2n before ending '"'.
        while (slashes-- > 0 && out != end) {
          *out++ = '\\';
        }
        if (out != end) {
          *out++ = '"';
        }
      }
    }
    if (out != end) {
      *out = '\0';
      newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(buffer);
    } else {
      newCommands[cp->NumberOfCommands] = 0;
    }
  }
  if (!newCommands[cp->NumberOfCommands]) {
    /* Out of memory or command line too long.  */
    free(newCommands);
    return 0;
  }

  /* Save the new array of commands.  */
  free(cp->Commands);
  cp->Commands = newCommands;
  cp->NumberOfCommands = newNumberOfCommands;
  return 1;
}

void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
{
  if (!cp) {
    return;
  }
  cp->Timeout = timeout;
  if (cp->Timeout < 0) {
    cp->Timeout = 0;
  }
  // Force recomputation of TimeoutTime.
  cp->TimeoutTime.QuadPart = -1;
}

int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
{
  if (!cp) {
    return 0;
  }
  if (cp->WorkingDirectory) {
    free(cp->WorkingDirectory);
    cp->WorkingDirectory = 0;
  }
  if (dir && dir[0]) {
    wchar_t* wdir = kwsysEncoding_DupToWide(dir);
    /* We must convert the working directory to a full path.  */
    DWORD length = GetFullPathNameW(wdir, 0, 0, 0);
    if (length > 0) {
      wchar_t* work_dir = malloc(length * sizeof(wchar_t));
      if (!work_dir) {
        free(wdir);
        return 0;
      }
      if (!GetFullPathNameW(wdir, length, work_dir, 0)) {
        free(work_dir);
        free(wdir);
        return 0;
      }
      cp->WorkingDirectory = work_dir;
    }
    free(wdir);
  }
  return 1;
}

int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
{
  char** pfile;
  if (!cp) {
    return 0;
  }
  switch (pipe) {
    case kwsysProcess_Pipe_STDIN:
      pfile = &cp->PipeFileSTDIN;
      break;
    case kwsysProcess_Pipe_STDOUT:
      pfile = &cp->PipeFileSTDOUT;
      break;
    case kwsysProcess_Pipe_STDERR:
      pfile = &cp->PipeFileSTDERR;
      break;
    default:
      return 0;
  }
  if (*pfile) {
    free(*pfile);
    *pfile = 0;
  }
  if (file) {
    *pfile = strdup(file);
    if (!*pfile) {
      return 0;
    }
  }

  /* If we are redirecting the pipe, do not share it or use a native
     pipe.  */
  if (*pfile) {
    kwsysProcess_SetPipeNative(cp, pipe, 0);
    kwsysProcess_SetPipeShared(cp, pipe, 0);
  }

  return 1;
}

void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
{
  if (!cp) {
    return;
  }

  switch (pipe) {
    case kwsysProcess_Pipe_STDIN:
      cp->PipeSharedSTDIN = shared ? 1 : 0;
      break;
    case kwsysProcess_Pipe_STDOUT:
      cp->PipeSharedSTDOUT = shared ? 1 : 0;
      break;
    case kwsysProcess_Pipe_STDERR:
      cp->PipeSharedSTDERR = shared ? 1 : 0;
      break;
    default:
      return;
  }

  /* If we are sharing the pipe, do not redirect it to a file or use a
     native pipe.  */
  if (shared) {
    kwsysProcess_SetPipeFile(cp, pipe, 0);
    kwsysProcess_SetPipeNative(cp, pipe, 0);
  }
}

void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, const HANDLE p[2])
{
  HANDLE* pPipeNative = 0;

  if (!cp) {
    return;
  }

  switch (pipe) {
    case kwsysProcess_Pipe_STDIN:
      pPipeNative = cp->PipeNativeSTDIN;
      break;
    case kwsysProcess_Pipe_STDOUT:
      pPipeNative = cp->PipeNativeSTDOUT;
      break;
    case kwsysProcess_Pipe_STDERR:
      pPipeNative = cp->PipeNativeSTDERR;
      break;
    default:
      return;
  }

  /* Copy the native pipe handles provided.  */
  if (p) {
    pPipeNative[0] = p[0];
    pPipeNative[1] = p[1];
  } else {
    pPipeNative[0] = 0;
    pPipeNative[1] = 0;
  }

  /* If we are using a native pipe, do not share it or redirect it to
     a file.  */
  if (p) {
    kwsysProcess_SetPipeFile(cp, pipe, 0);
    kwsysProcess_SetPipeShared(cp, pipe, 0);
  }
}

int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
{
  if (!cp) {
    return 0;
  }

  switch (optionId) {
    case kwsysProcess_Option_Detach:
      return cp->OptionDetach;
    case kwsysProcess_Option_HideWindow:
      return cp->HideWindow;
    case kwsysProcess_Option_MergeOutput:
      return cp->MergeOutput;
    case kwsysProcess_Option_Verbatim:
      return cp->Verbatim;
    case kwsysProcess_Option_CreateProcessGroup:
      return cp->CreateProcessGroup;
    default:
      return 0;
  }
}

void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
{
  if (!cp) {
    return;
  }

  switch (optionId) {
    case kwsysProcess_Option_Detach:
      cp->OptionDetach = value;
      break;
    case kwsysProcess_Option_HideWindow:
      cp->HideWindow = value;
      break;
    case kwsysProcess_Option_MergeOutput:
      cp->MergeOutput = value;
      break;
    case kwsysProcess_Option_Verbatim:
      cp->Verbatim = value;
      break;
    case kwsysProcess_Option_CreateProcessGroup:
      cp->CreateProcessGroup = value;
      break;
    default:
      break;
  }
}

int kwsysProcess_GetState(kwsysProcess* cp)
{
  return cp ? cp->State : kwsysProcess_State_Error;
}

int kwsysProcess_GetExitException(kwsysProcess* cp)
{
  return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0))
    ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitException
    : kwsysProcess_Exception_Other;
}

int kwsysProcess_GetExitValue(kwsysProcess* cp)
{
  return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0))
    ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitValue
    : -1;
}

int kwsysProcess_GetExitCode(kwsysProcess* cp)
{
  return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0))
    ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitCode
    : 0;
}

const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
{
  if (!cp) {
    return "Process management structure could not be allocated";
  } else if (cp->State == kwsysProcess_State_Error) {
    return cp->ErrorMessage;
  }
  return "Success";
}

const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
{
  if (!(cp && cp->ProcessResults && (cp->NumberOfCommands > 0))) {
    return "GetExceptionString called with NULL process management structure";
  } else if (cp->State == kwsysProcess_State_Exception) {
    return cp->ProcessResults[cp->NumberOfCommands - 1].ExitExceptionString;
  }
  return "No exception";
}

/* the index should be in array bound. */
#define KWSYSPE_IDX_CHK(RET)                                                  \
  if (!cp || idx >= cp->NumberOfCommands || idx < 0) {                        \
    KWSYSPE_DEBUG((stderr, "array index out of bound\n"));                    \
    return RET;                                                               \
  }

int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx)
{
  KWSYSPE_IDX_CHK(kwsysProcess_State_Error)
  return cp->ProcessResults[idx].State;
}

int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, int idx)
{
  KWSYSPE_IDX_CHK(kwsysProcess_Exception_Other)
  return cp->ProcessResults[idx].ExitException;
}

int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx)
{
  KWSYSPE_IDX_CHK(-1)
  return cp->ProcessResults[idx].ExitValue;
}

int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx)
{
  KWSYSPE_IDX_CHK(-1)
  return cp->CommandExitCodes[idx];
}

const char* kwsysProcess_GetExceptionStringByIndex(kwsysProcess* cp, int idx)
{
  KWSYSPE_IDX_CHK("GetExceptionString called with NULL process management "
                  "structure or index out of bound")
  if (cp->ProcessResults[idx].State == kwsysProcess_StateByIndex_Exception) {
    return cp->ProcessResults[idx].ExitExceptionString;
  }
  return "No exception";
}

#undef KWSYSPE_IDX_CHK

void kwsysProcess_Execute(kwsysProcess* cp)
{
  int i;

  /* Do not execute a second time.  */
  if (!cp || cp->State == kwsysProcess_State_Executing) {
    return;
  }

  /* Make sure we have something to run.  */
  if (cp->NumberOfCommands < 1) {
    strcpy(cp->ErrorMessage, "No command");
    cp->State = kwsysProcess_State_Error;
    return;
  }

  /* Initialize the control structure for a new process.  */
  if (!kwsysProcessInitialize(cp)) {
    strcpy(cp->ErrorMessage, "Out of memory");
    cp->State = kwsysProcess_State_Error;
    return;
  }

  /* Save the real working directory of this process and change to
     the working directory for the child processes.  This is needed
     to make pipe file paths evaluate correctly.  */
  if (cp->WorkingDirectory) {
    if (!GetCurrentDirectoryW(cp->RealWorkingDirectoryLength,
                              cp->RealWorkingDirectory)) {
      kwsysProcessCleanup(cp, GetLastError());
      return;
    }
    if (!SetCurrentDirectoryW(cp->WorkingDirectory)) {
      kwsysProcessCleanup(cp, GetLastError());
      return;
    }
  }

  /* Setup the stdin pipe for the first process.  */
  if (cp->PipeFileSTDIN) {
    /* Create a handle to read a file for stdin.  */
    wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN);
    DWORD error;
    cp->PipeChildStd[0] =
      CreateFileW(wstdin, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
                  OPEN_EXISTING, 0, 0);
    error = GetLastError(); /* Check now in case free changes this.  */
    free(wstdin);
    if (cp->PipeChildStd[0] == INVALID_HANDLE_VALUE) {
      kwsysProcessCleanup(cp, error);
      return;
    }
  } else if (cp->PipeSharedSTDIN) {
    /* Share this process's stdin with the child.  */
    kwsysProcessSetupSharedPipe(STD_INPUT_HANDLE, &cp->PipeChildStd[0]);
  } else if (cp->PipeNativeSTDIN[0]) {
    /* Use the provided native pipe.  */
    kwsysProcessSetupPipeNative(cp->PipeNativeSTDIN[0], &cp->PipeChildStd[0]);
  } else {
    /* Explicitly give the child no stdin.  */
    cp->PipeChildStd[0] = INVALID_HANDLE_VALUE;
  }

  /* Create the output pipe for the last process.
     We always create this so the pipe thread can run even if we
     do not end up giving the write end to the child below.  */
  if (!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDOUT].Read,
                  &cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, 0, 0)) {
    kwsysProcessCleanup(cp, GetLastError());
    return;
  }

  if (cp->PipeFileSTDOUT) {
    /* Use a file for stdout.  */
    DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
                                                  cp->PipeFileSTDOUT);
    if (error) {
      kwsysProcessCleanup(cp, error);
      return;
    }
  } else if (cp->PipeSharedSTDOUT) {
    /* Use the parent stdout.  */
    kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE, &cp->PipeChildStd[1]);
  } else if (cp->PipeNativeSTDOUT[1]) {
    /* Use the given handle for stdout.  */
    kwsysProcessSetupPipeNative(cp->PipeNativeSTDOUT[1], &cp->PipeChildStd[1]);
  } else {
    /* Use our pipe for stdout.  Duplicate the handle since our waker
       thread will use the original.  Do not make it inherited yet.  */
    if (!DuplicateHandle(GetCurrentProcess(),
                         cp->Pipe[KWSYSPE_PIPE_STDOUT].Write,
                         GetCurrentProcess(), &cp->PipeChildStd[1], 0, FALSE,
                         DUPLICATE_SAME_ACCESS)) {
      kwsysProcessCleanup(cp, GetLastError());
      return;
    }
  }

  /* Create stderr pipe to be shared by all processes in the pipeline.
     We always create this so the pipe thread can run even if we do not
     end up giving the write end to the child below.  */
  if (!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
                  &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0)) {
    kwsysProcessCleanup(cp, GetLastError());
    return;
  }

  if (cp->PipeFileSTDERR) {
    /* Use a file for stderr.  */
    DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
                                                  cp->PipeFileSTDERR);
    if (error) {
      kwsysProcessCleanup(cp, error);
      return;
    }
  } else if (cp->PipeSharedSTDERR) {
    /* Use the parent stderr.  */
    kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE, &cp->PipeChildStd[2]);
  } else if (cp->PipeNativeSTDERR[1]) {
    /* Use the given handle for stderr.  */
    kwsysProcessSetupPipeNative(cp->PipeNativeSTDERR[1], &cp->PipeChildStd[2]);
  } else {
    /* Use our pipe for stderr.  Duplicate the handle since our waker
       thread will use the original.  Do not make it inherited yet.  */
    if (!DuplicateHandle(GetCurrentProcess(),
                         cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
                         GetCurrentProcess(), &cp->PipeChildStd[2], 0, FALSE,
                         DUPLICATE_SAME_ACCESS)) {
      kwsysProcessCleanup(cp, GetLastError());
      return;
    }
  }

  /* Create the pipeline of processes.  */
  {
    /* Child startup control data.  */
    kwsysProcessCreateInformation si;
    HANDLE nextStdInput = cp->PipeChildStd[0];

    /* Initialize startup info data.  */
    ZeroMemory(&si, sizeof(si));
    si.StartupInfo.cb = sizeof(si.StartupInfo);

    /* Decide whether a child window should be shown.  */
    si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
    si.StartupInfo.wShowWindow =
      (unsigned short)(cp->HideWindow ? SW_HIDE : SW_SHOWDEFAULT);

    /* Connect the child's output pipes to the threads.  */
    si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;

    for (i = 0; i < cp->NumberOfCommands; ++i) {
      /* Setup the process's pipes.  */
      si.hStdInput = nextStdInput;
      if (i == cp->NumberOfCommands - 1) {
        /* The last child gets the overall stdout.  */
        nextStdInput = INVALID_HANDLE_VALUE;
        si.hStdOutput = cp->PipeChildStd[1];
      } else {
        /* Create a pipe to sit between the children.  */
        HANDLE p[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
        if (!CreatePipe(&p[0], &p[1], 0, 0)) {
          DWORD error = GetLastError();
          if (nextStdInput != cp->PipeChildStd[0]) {
            kwsysProcessCleanupHandle(&nextStdInput);
          }
          kwsysProcessCleanup(cp, error);
          return;
        }
        nextStdInput = p[0];
        si.hStdOutput = p[1];
      }
      si.hStdError =
        cp->MergeOutput ? cp->PipeChildStd[1] : cp->PipeChildStd[2];

      {
        DWORD error = kwsysProcessCreate(cp, i, &si);

        /* Close our copies of pipes used between children.  */
        if (si.hStdInput != cp->PipeChildStd[0]) {
          kwsysProcessCleanupHandle(&si.hStdInput);
        }
        if (si.hStdOutput != cp->PipeChildStd[1]) {
          kwsysProcessCleanupHandle(&si.hStdOutput);
        }
        if (si.hStdError != cp->PipeChildStd[2] && !cp->MergeOutput) {
          kwsysProcessCleanupHandle(&si.hStdError);
        }
        if (!error) {
          cp->ProcessEvents[i + 1] = cp->ProcessInformation[i].hProcess;
        } else {
          if (nextStdInput != cp->PipeChildStd[0]) {
            kwsysProcessCleanupHandle(&nextStdInput);
          }
          kwsysProcessCleanup(cp, error);
          return;
        }
      }
    }
  }

  /* The parent process does not need the child's pipe ends.  */
  for (i = 0; i < 3; ++i) {
    kwsysProcessCleanupHandle(&cp->PipeChildStd[i]);
  }

  /* Restore the working directory.  */
  if (cp->RealWorkingDirectory) {
    SetCurrentDirectoryW(cp->RealWorkingDirectory);
    free(cp->RealWorkingDirectory);
    cp->RealWorkingDirectory = 0;
  }

  /* The timeout period starts now.  */
  cp->StartTime = kwsysProcessTimeGetCurrent();
  cp->TimeoutTime = kwsysProcessTimeFromDouble(-1);

  /* All processes in the pipeline have been started in suspended
     mode.  Resume them all now.  */
  for (i = 0; i < cp->NumberOfCommands; ++i) {
    ResumeThread(cp->ProcessInformation[i].hThread);
  }

  /* ---- It is no longer safe to call kwsysProcessCleanup. ----- */
  /* Tell the pipe threads that a process has started.  */
  for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
    ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);
    ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);
  }

  /* We don't care about the children's main threads.  */
  for (i = 0; i < cp->NumberOfCommands; ++i) {
    kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
  }

  /* No pipe has reported data.  */
  cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
  cp->PipesLeft = KWSYSPE_PIPE_COUNT;

  /* The process has now started.  */
  cp->State = kwsysProcess_State_Executing;
  cp->Detached = cp->OptionDetach;
}

void kwsysProcess_Disown(kwsysProcess* cp)
{
  int i;

  /* Make sure we are executing a detached process.  */
  if (!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
      cp->TimeoutExpired || cp->Killed || cp->Terminated) {
    return;
  }

  /* Disable the reading threads.  */
  kwsysProcessDisablePipeThreads(cp);

  /* Wait for all pipe threads to reset.  */
  for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
    WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE);
    WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE);
  }

  /* We will not wait for exit, so cleanup now.  */
  kwsysProcessCleanup(cp, 0);

  /* The process has been disowned.  */
  cp->State = kwsysProcess_State_Disowned;
}

int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
                             double* userTimeout)
{
  kwsysProcessTime userStartTime;
  kwsysProcessTime timeoutLength;
  kwsysProcessTime timeoutTime;
  DWORD timeout;
  int user;
  int done = 0;
  int expired = 0;
  int pipeId = kwsysProcess_Pipe_None;
  DWORD w;

  /* Make sure we are executing a process.  */
  if (!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
      cp->TimeoutExpired) {
    return kwsysProcess_Pipe_None;
  }

  /* Record the time at which user timeout period starts.  */
  userStartTime = kwsysProcessTimeGetCurrent();

  /* Calculate the time at which a timeout will expire, and whether it
     is the user or process timeout.  */
  user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime);

  /* Loop until we have a reason to return.  */
  while (!done && cp->PipesLeft > 0) {
    /* If we previously got data from a thread, let it know we are
       done with the data.  */
    if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) {
      KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
      ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
      cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
    }

    /* Setup a timeout if required.  */
    if (kwsysProcessGetTimeoutLeft(&timeoutTime, user ? userTimeout : 0,
                                   &timeoutLength)) {
      /* Timeout has already expired.  */
      expired = 1;
      break;
    }
    if (timeoutTime.QuadPart < 0) {
      timeout = INFINITE;
    } else {
      timeout = kwsysProcessTimeToDWORD(timeoutLength);
    }

    /* Wait for a pipe's thread to signal or a process to terminate.  */
    w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents, 0,
                               timeout);
    if (w == WAIT_TIMEOUT) {
      /* Timeout has expired.  */
      expired = 1;
      done = 1;
    } else if (w == WAIT_OBJECT_0) {
      /* Save the index of the reporting thread and release the mutex.
         The thread will block until we signal its Empty mutex.  */
      cp->CurrentIndex = cp->SharedIndex;
      ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);

      /* Data are available or a pipe closed.  */
      if (cp->Pipe[cp->CurrentIndex].Closed) {
        /* The pipe closed at the write end.  Close the read end and
           inform the wakeup thread it is done with this process.  */
        kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read);
        ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Waker.Go, 1, 0);
        KWSYSPE_DEBUG((stderr, "wakeup %d\n", cp->CurrentIndex));
        --cp->PipesLeft;
      } else if (data && length) {
        /* Report this data.  */
        *data = cp->Pipe[cp->CurrentIndex].DataBuffer;
        *length = cp->Pipe[cp->CurrentIndex].DataLength;
        switch (cp->CurrentIndex) {
          case KWSYSPE_PIPE_STDOUT:
            pipeId = kwsysProcess_Pipe_STDOUT;
            break;
          case KWSYSPE_PIPE_STDERR:
            pipeId = kwsysProcess_Pipe_STDERR;
            break;
        }
        done = 1;
      }
    } else {
      /* A process has terminated.  */
      kwsysProcessDestroy(cp, w - WAIT_OBJECT_0);
    }
  }

  /* Update the user timeout.  */
  if (userTimeout) {
    kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent();
    kwsysProcessTime difference =
      kwsysProcessTimeSubtract(userEndTime, userStartTime);
    double d = kwsysProcessTimeToDouble(difference);
    *userTimeout -= d;
    if (*userTimeout < 0) {
      *userTimeout = 0;
    }
  }

  /* Check what happened.  */
  if (pipeId) {
    /* Data are ready on a pipe.  */
    return pipeId;
  } else if (expired) {
    /* A timeout has expired.  */
    if (user) {
      /* The user timeout has expired.  It has no time left.  */
      return kwsysProcess_Pipe_Timeout;
    } else {
      /* The process timeout has expired.  Kill the child now.  */
      KWSYSPE_DEBUG((stderr, "killing child because timeout expired\n"));
      kwsysProcess_Kill(cp);
      cp->TimeoutExpired = 1;
      cp->Killed = 0;
      return kwsysProcess_Pipe_None;
    }
  } else {
    /* The children have terminated and no more data are available.  */
    return kwsysProcess_Pipe_None;
  }
}

int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
{
  int i;
  int pipe;

  /* Make sure we are executing a process.  */
  if (!cp || cp->State != kwsysProcess_State_Executing) {
    return 1;
  }

  /* Wait for the process to terminate.  Ignore all data.  */
  while ((pipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0) {
    if (pipe == kwsysProcess_Pipe_Timeout) {
      /* The user timeout has expired.  */
      return 0;
    }
  }

  KWSYSPE_DEBUG((stderr, "no more data\n"));

  /* When the last pipe closes in WaitForData, the loop terminates
     without releasing the pipe's thread.  Release it now.  */
  if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) {
    KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
    ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
    cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
  }

  /* Wait for all pipe threads to reset.  */
  for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
    KWSYSPE_DEBUG((stderr, "waiting reader reset %d\n", i));
    WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE);
    KWSYSPE_DEBUG((stderr, "waiting waker reset %d\n", i));
    WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE);
  }

  /* ---- It is now safe again to call kwsysProcessCleanup. ----- */
  /* Close all the pipes.  */
  kwsysProcessCleanup(cp, 0);

  /* Determine the outcome.  */
  if (cp->Killed) {
    /* We killed the child.  */
    cp->State = kwsysProcess_State_Killed;
  } else if (cp->TimeoutExpired) {
    /* The timeout expired.  */
    cp->State = kwsysProcess_State_Expired;
  } else {
    /* The children exited.  Report the outcome of the child processes.  */
    for (i = 0; i < cp->NumberOfCommands; ++i) {
      cp->ProcessResults[i].ExitCode = cp->CommandExitCodes[i];
      if ((cp->ProcessResults[i].ExitCode & 0xF0000000) == 0xC0000000) {
        /* Child terminated due to exceptional behavior.  */
        cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Exception;
        cp->ProcessResults[i].ExitValue = 1;
        kwsysProcessSetExitExceptionByIndex(cp, cp->ProcessResults[i].ExitCode,
                                            i);
      } else {
        /* Child exited without exception.  */
        cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Exited;
        cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None;
        cp->ProcessResults[i].ExitValue = cp->ProcessResults[i].ExitCode;
      }
    }
    /* support legacy state status value */
    cp->State = cp->ProcessResults[cp->NumberOfCommands - 1].State;
  }

  return 1;
}

void kwsysProcess_Interrupt(kwsysProcess* cp)
{
  int i;
  /* Make sure we are executing a process.  */
  if (!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
      cp->Killed) {
    KWSYSPE_DEBUG((stderr, "interrupt: child not executing\n"));
    return;
  }

  /* Skip actually interrupting the child if it has already terminated.  */
  if (cp->Terminated) {
    KWSYSPE_DEBUG((stderr, "interrupt: child already terminated\n"));
    return;
  }

  /* Interrupt the children.  */
  if (cp->CreateProcessGroup) {
    if (cp->ProcessInformation) {
      for (i = 0; i < cp->NumberOfCommands; ++i) {
        /* Make sure the process handle isn't closed (e.g. from disowning). */
        if (cp->ProcessInformation[i].hProcess) {
          /* The user created a process group for this process.  The group ID
             is the process ID for the original process in the group.  Note
             that we have to use Ctrl+Break: Ctrl+C is not allowed for process
             groups.  */
          GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
                                   cp->ProcessInformation[i].dwProcessId);
        }
      }
    }
  } else {
    /* No process group was created.  Kill our own process group...  */
    GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
  }
}

void kwsysProcess_Kill(kwsysProcess* cp)
{
  int i;
  /* Make sure we are executing a process.  */
  if (!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
      cp->Killed) {
    KWSYSPE_DEBUG((stderr, "kill: child not executing\n"));
    return;
  }

  /* Disable the reading threads.  */
  KWSYSPE_DEBUG((stderr, "kill: disabling pipe threads\n"));
  kwsysProcessDisablePipeThreads(cp);

  /* Skip actually killing the child if it has already terminated.  */
  if (cp->Terminated) {
    KWSYSPE_DEBUG((stderr, "kill: child already terminated\n"));
    return;
  }

  /* Kill the children.  */
  cp->Killed = 1;
  for (i = 0; i < cp->NumberOfCommands; ++i) {
    kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
    /* Remove from global list of processes and close handles.  */
    kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
    kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
    kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
  }

  /* We are killing the children and ignoring all data.  Do not wait
     for them to exit.  */
}

void kwsysProcess_KillPID(unsigned long process_id)
{
  kwsysProcessKillTree((DWORD)process_id);
}

/*
  Function executed for each pipe's thread.  Argument is a pointer to
  the kwsysProcessPipeData instance for this thread.
*/
DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd)
{
  kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd;
  kwsysProcess* cp = td->Process;

  /* Wait for a process to be ready.  */
  while ((WaitForSingleObject(td->Reader.Ready, INFINITE), !cp->Deleting)) {
    /* Read output from the process for this thread's pipe.  */
    kwsysProcessPipeThreadReadPipe(cp, td);

    /* Signal the main thread we have reset for a new process.  */
    ReleaseSemaphore(td->Reader.Reset, 1, 0);
  }
  return 0;
}

/*
  Function called in each pipe's thread to handle data for one
  execution of a subprocess.
*/
void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td)
{
  /* Wait for space in the thread's buffer. */
  while ((KWSYSPE_DEBUG((stderr, "wait for read %d\n", td->Index)),
          WaitForSingleObject(td->Reader.Go, INFINITE), !td->Closed)) {
    KWSYSPE_DEBUG((stderr, "reading %d\n", td->Index));

    /* Read data from the pipe.  This may block until data are available.  */
    if (!ReadFile(td->Read, td->DataBuffer, KWSYSPE_PIPE_BUFFER_SIZE,
                  &td->DataLength, 0)) {
      if (GetLastError() != ERROR_BROKEN_PIPE) {
        /* UNEXPECTED failure to read the pipe.  */
      }

      /* The pipe closed.  There are no more data to read.  */
      td->Closed = 1;
      KWSYSPE_DEBUG((stderr, "read closed %d\n", td->Index));
    }

    KWSYSPE_DEBUG((stderr, "read %d\n", td->Index));

    /* Wait for our turn to be handled by the main thread.  */
    WaitForSingleObject(cp->SharedIndexMutex, INFINITE);

    KWSYSPE_DEBUG((stderr, "reporting read %d\n", td->Index));

    /* Tell the main thread we have something to report.  */
    cp->SharedIndex = td->Index;
    ReleaseSemaphore(cp->Full, 1, 0);
  }

  /* We were signalled to exit with our buffer empty.  Reset the
     mutex for a new process.  */
  KWSYSPE_DEBUG((stderr, "self releasing reader %d\n", td->Index));
  ReleaseSemaphore(td->Reader.Go, 1, 0);
}

/*
  Function executed for each pipe's thread.  Argument is a pointer to
  the kwsysProcessPipeData instance for this thread.
*/
DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd)
{
  kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd;
  kwsysProcess* cp = td->Process;

  /* Wait for a process to be ready.  */
  while ((WaitForSingleObject(td->Waker.Ready, INFINITE), !cp->Deleting)) {
    /* Wait for a possible wakeup.  */
    kwsysProcessPipeThreadWakePipe(cp, td);

    /* Signal the main thread we have reset for a new process.  */
    ReleaseSemaphore(td->Waker.Reset, 1, 0);
  }
  return 0;
}

/*
  Function called in each pipe's thread to handle reading thread
  wakeup for one execution of a subprocess.
*/
void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp, kwsysProcessPipeData* td)
{
  (void)cp;

  /* Wait for a possible wake command. */
  KWSYSPE_DEBUG((stderr, "wait for wake %d\n", td->Index));
  WaitForSingleObject(td->Waker.Go, INFINITE);
  KWSYSPE_DEBUG((stderr, "waking %d\n", td->Index));

  /* If the pipe is not closed, we need to wake up the reading thread.  */
  if (!td->Closed) {
    DWORD dummy;
    KWSYSPE_DEBUG((stderr, "waker %d writing byte\n", td->Index));
    WriteFile(td->Write, "", 1, &dummy, 0);
    KWSYSPE_DEBUG((stderr, "waker %d wrote byte\n", td->Index));
  }
}

/* Initialize a process control structure for kwsysProcess_Execute.  */
int kwsysProcessInitialize(kwsysProcess* cp)
{
  int i;
  /* Reset internal status flags.  */
  cp->TimeoutExpired = 0;
  cp->Terminated = 0;
  cp->Killed = 0;

  free(cp->ProcessResults);
  /* Allocate process result information for each process.  */
  cp->ProcessResults = (kwsysProcessResults*)malloc(
    sizeof(kwsysProcessResults) * (cp->NumberOfCommands));
  if (!cp->ProcessResults) {
    return 0;
  }
  ZeroMemory(cp->ProcessResults,
             sizeof(kwsysProcessResults) * cp->NumberOfCommands);
  for (i = 0; i < cp->NumberOfCommands; i++) {
    cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None;
    cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Starting;
    cp->ProcessResults[i].ExitCode = 1;
    cp->ProcessResults[i].ExitValue = 1;
    strcpy(cp->ProcessResults[i].ExitExceptionString, "No exception");
  }

  /* Allocate process information for each process.  */
  free(cp->ProcessInformation);
  cp->ProcessInformation = (PROCESS_INFORMATION*)malloc(
    sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
  if (!cp->ProcessInformation) {
    return 0;
  }
  ZeroMemory(cp->ProcessInformation,
             sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
  free(cp->CommandExitCodes);
  cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD) * cp->NumberOfCommands);
  if (!cp->CommandExitCodes) {
    return 0;
  }
  ZeroMemory(cp->CommandExitCodes, sizeof(DWORD) * cp->NumberOfCommands);

  /* Allocate event wait array.  The first event is cp->Full, the rest
     are the process termination events.  */
  cp->ProcessEvents =
    (PHANDLE)malloc(sizeof(HANDLE) * (cp->NumberOfCommands + 1));
  if (!cp->ProcessEvents) {
    return 0;
  }
  ZeroMemory(cp->ProcessEvents, sizeof(HANDLE) * (cp->NumberOfCommands + 1));
  cp->ProcessEvents[0] = cp->Full;
  cp->ProcessEventsLength = cp->NumberOfCommands + 1;

  /* Allocate space to save the real working directory of this process.  */
  if (cp->WorkingDirectory) {
    cp->RealWorkingDirectoryLength = GetCurrentDirectoryW(0, 0);
    if (cp->RealWorkingDirectoryLength > 0) {
      cp->RealWorkingDirectory =
        malloc(cp->RealWorkingDirectoryLength * sizeof(wchar_t));
      if (!cp->RealWorkingDirectory) {
        return 0;
      }
    }
  }
  {
    for (i = 0; i < 3; ++i) {
      cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
    }
  }

  return 1;
}

static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
{
  DWORD flags;

  /* Check whether the handle is valid for this process.  */
  if (in != INVALID_HANDLE_VALUE && GetHandleInformation(in, &flags)) {
    /* Use the handle as-is if it is already inherited.  */
    if (flags & HANDLE_FLAG_INHERIT) {
      *out = in;
      return ERROR_SUCCESS;
    }

    /* Create an inherited copy of this handle.  */
    if (DuplicateHandle(GetCurrentProcess(), in, GetCurrentProcess(), out, 0,
                        TRUE, DUPLICATE_SAME_ACCESS)) {
      return ERROR_SUCCESS;
    } else {
      return GetLastError();
    }
  } else {
    /* The given handle is not valid for this process.  Some child
       processes may break if they do not have a valid standard handle,
       so open NUL to give to the child.  */
    SECURITY_ATTRIBUTES sa;
    ZeroMemory(&sa, sizeof(sa));
    sa.nLength = (DWORD)sizeof(sa);
    sa.bInheritHandle = 1;
    *out = CreateFileW(
      L"NUL",
      (isStdIn ? GENERIC_READ : (GENERIC_WRITE | FILE_READ_ATTRIBUTES)),
      FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, 0);
    return (*out != INVALID_HANDLE_VALUE) ? ERROR_SUCCESS : GetLastError();
  }
}

DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
                         kwsysProcessCreateInformation* si)
{
  DWORD creationFlags;
  DWORD error = ERROR_SUCCESS;

  /* Check if we are currently exiting.  */
  if (!kwsysTryEnterCreateProcessSection()) {
    /* The Ctrl handler is currently working on exiting our process.  Rather
    than return an error code, which could cause incorrect conclusions to be
    reached by the caller, we simply hang.  (For example, a CMake try_run
    configure step might cause the project to configure wrong.)  */
    Sleep(INFINITE);
  }

  /* Create the child in a suspended state so we can wait until all
     children have been created before running any one.  */
  creationFlags = CREATE_SUSPENDED;
  if (cp->CreateProcessGroup) {
    creationFlags |= CREATE_NEW_PROCESS_GROUP;
  }

  /* Create inherited copies of the handles.  */
  (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput,
                                         si->hStdInput, 1)) ||
    (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
                                           si->hStdOutput, 0)) ||
    (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
                                           si->hStdError, 0)) ||
    /* Create the process.  */
    (!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, creationFlags, 0, 0,
                     &si->StartupInfo, &cp->ProcessInformation[index]) &&
     (error = GetLastError()));

  /* Close the inherited copies of the handles. */
  if (si->StartupInfo.hStdInput != si->hStdInput) {
    kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput);
  }
  if (si->StartupInfo.hStdOutput != si->hStdOutput) {
    kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
  }
  if (si->StartupInfo.hStdError != si->hStdError) {
    kwsysProcessCleanupHandle(&si->StartupInfo.hStdError);
  }

  /* Add the process to the global list of processes. */
  if (!error &&
      !kwsysProcessesAdd(cp->ProcessInformation[index].hProcess,
                         cp->ProcessInformation[index].dwProcessId,
                         cp->CreateProcessGroup)) {
    /* This failed for some reason.  Kill the suspended process. */
    TerminateProcess(cp->ProcessInformation[index].hProcess, 1);
    /* And clean up... */
    kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
    kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
    strcpy(cp->ErrorMessage, "kwsysProcessesAdd function failed");
    error = ERROR_NOT_ENOUGH_MEMORY; /* Most likely reason.  */
  }

  /* If the console Ctrl handler is waiting for us, this will release it... */
  kwsysLeaveCreateProcessSection();
  return error;
}

void kwsysProcessDestroy(kwsysProcess* cp, int event)
{
  int i;
  int index;

  /* Find the process index for the termination event.  */
  for (index = 0; index < cp->NumberOfCommands; ++index) {
    if (cp->ProcessInformation[index].hProcess == cp->ProcessEvents[event]) {
      break;
    }
  }

  /* Check the exit code of the process.  */
  GetExitCodeProcess(cp->ProcessInformation[index].hProcess,
                     &cp->CommandExitCodes[index]);

  /* Remove from global list of processes.  */
  kwsysProcessesRemove(cp->ProcessInformation[index].hProcess);

  /* Close the process handle for the terminated process.  */
  kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);

  /* Remove the process from the available events.  */
  cp->ProcessEventsLength -= 1;
  for (i = event; i < cp->ProcessEventsLength; ++i) {
    cp->ProcessEvents[i] = cp->ProcessEvents[i + 1];
  }

  /* Check if all processes have terminated.  */
  if (cp->ProcessEventsLength == 1) {
    cp->Terminated = 1;

    /* Close our copies of the pipe write handles so the pipe threads
       can detect end-of-data.  */
    for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
      /* TODO: If the child created its own child (our grandchild)
         which inherited a copy of the pipe write-end then the pipe
         may not close and we will still need the waker write pipe.
         However we still want to be able to detect end-of-data in the
         normal case.  The reader thread will have to switch to using
         PeekNamedPipe to read the last bit of data from the pipe
         without blocking.  This is equivalent to using a non-blocking
         read on posix.  */
      KWSYSPE_DEBUG((stderr, "closing wakeup write %d\n", i));
      kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
    }
  }
}

DWORD kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
{
  HANDLE fout;
  wchar_t* wname;
  DWORD error;
  if (!name) {
    return ERROR_INVALID_PARAMETER;
  }

  /* Close the existing handle.  */
  kwsysProcessCleanupHandle(phandle);

  /* Create a handle to write a file for the pipe.  */
  wname = kwsysEncoding_DupToWide(name);
  fout =
    CreateFileW(wname, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
  error = GetLastError();
  free(wname);
  if (fout == INVALID_HANDLE_VALUE) {
    return error;
  }

  /* Assign the replacement handle.  */
  *phandle = fout;
  return ERROR_SUCCESS;
}

void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle)
{
  /* Close the existing handle.  */
  kwsysProcessCleanupHandle(handle);
  /* Store the new standard handle.  */
  *handle = GetStdHandle(nStdHandle);
}

void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle)
{
  /* Close the existing handle.  */
  kwsysProcessCleanupHandle(handle);
  /* Store the new given handle.  */
  *handle = native;
}

/* Close the given handle if it is open.  Reset its value to 0.  */
void kwsysProcessCleanupHandle(PHANDLE h)
{
  if (h && *h && *h != INVALID_HANDLE_VALUE &&
      *h != GetStdHandle(STD_INPUT_HANDLE) &&
      *h != GetStdHandle(STD_OUTPUT_HANDLE) &&
      *h != GetStdHandle(STD_ERROR_HANDLE)) {
    CloseHandle(*h);
    *h = INVALID_HANDLE_VALUE;
  }
}

/* Close all handles created by kwsysProcess_Execute.  */
void kwsysProcessCleanup(kwsysProcess* cp, DWORD error)
{
  int i;
  /* If this is an error case, report the error.  */
  if (error) {
    /* Construct an error message if one has not been provided already.  */
    if (cp->ErrorMessage[0] == 0) {
      /* Format the error message.  */
      wchar_t err_msg[KWSYSPE_PIPE_BUFFER_SIZE];
      DWORD length = FormatMessageW(
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_msg,
        KWSYSPE_PIPE_BUFFER_SIZE, 0);
      if (length < 1) {
        /* FormatMessage failed.  Use a default message.  */
        snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
                 "Process execution failed with error 0x%lX.  "
                 "FormatMessage failed with error 0x%lX",
                 error, GetLastError());
      }
      if (!WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage,
                               KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL)) {
        /* WideCharToMultiByte failed.  Use a default message.  */
        snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
                 "Process execution failed with error 0x%lX.  "
                 "WideCharToMultiByte failed with error 0x%lX",
                 error, GetLastError());
      }
    }

    /* Remove trailing period and newline, if any.  */
    kwsysProcessCleanErrorMessage(cp);

    /* Set the error state.  */
    cp->State = kwsysProcess_State_Error;

    /* Cleanup any processes already started in a suspended state.  */
    if (cp->ProcessInformation) {
      for (i = 0; i < cp->NumberOfCommands; ++i) {
        if (cp->ProcessInformation[i].hProcess) {
          TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
          WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
        }
      }
      for (i = 0; i < cp->NumberOfCommands; ++i) {
        /* Remove from global list of processes and close handles.  */
        kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
        kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
        kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
      }
    }

    /* Restore the working directory.  */
    if (cp->RealWorkingDirectory) {
      SetCurrentDirectoryW(cp->RealWorkingDirectory);
    }
  }

  /* Free memory.  */
  if (cp->ProcessInformation) {
    free(cp->ProcessInformation);
    cp->ProcessInformation = 0;
  }
  if (cp->ProcessEvents) {
    free(cp->ProcessEvents);
    cp->ProcessEvents = 0;
  }
  if (cp->RealWorkingDirectory) {
    free(cp->RealWorkingDirectory);
    cp->RealWorkingDirectory = 0;
  }

  /* Close each pipe.  */
  for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
    kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Read);
    cp->Pipe[i].Closed = 0;
  }
  for (i = 0; i < 3; ++i) {
    kwsysProcessCleanupHandle(&cp->PipeChildStd[i]);
  }
}

void kwsysProcessCleanErrorMessage(kwsysProcess* cp)
{
  /* Remove trailing period and newline, if any.  */
  size_t length = strlen(cp->ErrorMessage);
  if (cp->ErrorMessage[length - 1] == '\n') {
    cp->ErrorMessage[length - 1] = 0;
    --length;
    if (length > 0 && cp->ErrorMessage[length - 1] == '\r') {
      cp->ErrorMessage[length - 1] = 0;
      --length;
    }
  }
  if (length > 0 && cp->ErrorMessage[length - 1] == '.') {
    cp->ErrorMessage[length - 1] = 0;
  }
}

/* Get the time at which either the process or user timeout will
   expire.  Returns 1 if the user timeout is first, and 0 otherwise.  */
int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
                               kwsysProcessTime* timeoutTime)
{
  /* The first time this is called, we need to calculate the time at
     which the child will timeout.  */
  if (cp->Timeout && cp->TimeoutTime.QuadPart < 0) {
    kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout);
    cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length);
  }

  /* Start with process timeout.  */
  *timeoutTime = cp->TimeoutTime;

  /* Check if the user timeout is earlier.  */
  if (userTimeout) {
    kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
    kwsysProcessTime userTimeoutLength =
      kwsysProcessTimeFromDouble(*userTimeout);
    kwsysProcessTime userTimeoutTime =
      kwsysProcessTimeAdd(currentTime, userTimeoutLength);
    if (timeoutTime->QuadPart < 0 ||
        kwsysProcessTimeLess(userTimeoutTime, *timeoutTime)) {
      *timeoutTime = userTimeoutTime;
      return 1;
    }
  }
  return 0;
}

/* Get the length of time before the given timeout time arrives.
   Returns 1 if the time has already arrived, and 0 otherwise.  */
int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
                               double* userTimeout,
                               kwsysProcessTime* timeoutLength)
{
  if (timeoutTime->QuadPart < 0) {
    /* No timeout time has been requested.  */
    return 0;
  } else {
    /* Calculate the remaining time.  */
    kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
    *timeoutLength = kwsysProcessTimeSubtract(*timeoutTime, currentTime);

    if (timeoutLength->QuadPart < 0 && userTimeout && *userTimeout <= 0) {
      /* Caller has explicitly requested a zero timeout.  */
      timeoutLength->QuadPart = 0;
    }

    if (timeoutLength->QuadPart < 0) {
      /* Timeout has already expired.  */
      return 1;
    } else {
      /* There is some time left.  */
      return 0;
    }
  }
}

kwsysProcessTime kwsysProcessTimeGetCurrent()
{
  kwsysProcessTime current;
  FILETIME ft;
  GetSystemTimeAsFileTime(&ft);
  current.LowPart = ft.dwLowDateTime;
  current.HighPart = ft.dwHighDateTime;
  return current;
}

DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t)
{
  return (DWORD)(t.QuadPart * 0.0001);
}

double kwsysProcessTimeToDouble(kwsysProcessTime t)
{
  return t.QuadPart * 0.0000001;
}

kwsysProcessTime kwsysProcessTimeFromDouble(double d)
{
  kwsysProcessTime t;
  t.QuadPart = (LONGLONG)(d * 10000000);
  return t;
}

int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2)
{
  return in1.QuadPart < in2.QuadPart;
}

kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1,
                                     kwsysProcessTime in2)
{
  kwsysProcessTime out;
  out.QuadPart = in1.QuadPart + in2.QuadPart;
  return out;
}

kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1,
                                          kwsysProcessTime in2)
{
  kwsysProcessTime out;
  out.QuadPart = in1.QuadPart - in2.QuadPart;
  return out;
}

#define KWSYSPE_CASE(type, str)                                               \
  cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_##type;      \
  strcpy(cp->ProcessResults[idx].ExitExceptionString, str)
static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int code,
                                                int idx)
{
  switch (code) {
    case STATUS_CONTROL_C_EXIT:
      KWSYSPE_CASE(Interrupt, "User interrupt");
      break;

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

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

    case STATUS_ILLEGAL_INSTRUCTION:
      KWSYSPE_CASE(Illegal, "Illegal instruction");
      break;
    case STATUS_PRIVILEGED_INSTRUCTION:
      KWSYSPE_CASE(Illegal, "Privileged instruction");
      break;

    case STATUS_NO_MEMORY:
    default:
      cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_Other;
      snprintf(cp->ProcessResults[idx].ExitExceptionString,
               KWSYSPE_PIPE_BUFFER_SIZE, "Exit code 0x%x\n", code);
      break;
  }
}
#undef KWSYSPE_CASE

typedef struct kwsysProcess_List_s kwsysProcess_List;
static kwsysProcess_List* kwsysProcess_List_New(void);
static void kwsysProcess_List_Delete(kwsysProcess_List* self);
static int kwsysProcess_List_Update(kwsysProcess_List* self);
static int kwsysProcess_List_NextProcess(kwsysProcess_List* self);
static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self);
static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self);

/* Windows NT 4 API definitions.  */
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
typedef LONG NTSTATUS;
typedef LONG KPRIORITY;
typedef struct _UNICODE_STRING UNICODE_STRING;
struct _UNICODE_STRING
{
  USHORT Length;
  USHORT MaximumLength;
  PWSTR Buffer;
};

/* The process information structure.  Declare only enough to get
   process identifiers.  The rest may be ignored because we use the
   NextEntryDelta to move through an array of instances.  */
typedef struct _SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION;
typedef SYSTEM_PROCESS_INFORMATION* PSYSTEM_PROCESS_INFORMATION;
struct _SYSTEM_PROCESS_INFORMATION
{
  ULONG NextEntryDelta;
  ULONG ThreadCount;
  ULONG Reserved1[6];
  LARGE_INTEGER CreateTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER KernelTime;
  UNICODE_STRING ProcessName;
  KPRIORITY BasePriority;
  ULONG ProcessId;
  ULONG InheritedFromProcessId;
};

/* Toolhelp32 API definitions.  */
#define TH32CS_SNAPPROCESS 0x00000002
#if defined(_WIN64)
typedef unsigned __int64 ProcessULONG_PTR;
#else
typedef unsigned long ProcessULONG_PTR;
#endif
typedef struct tagPROCESSENTRY32 PROCESSENTRY32;
typedef PROCESSENTRY32* LPPROCESSENTRY32;
struct tagPROCESSENTRY32
{
  DWORD dwSize;
  DWORD cntUsage;
  DWORD th32ProcessID;
  ProcessULONG_PTR th32DefaultHeapID;
  DWORD th32ModuleID;
  DWORD cntThreads;
  DWORD th32ParentProcessID;
  LONG pcPriClassBase;
  DWORD dwFlags;
  char szExeFile[MAX_PATH];
};

/* Windows API function types.  */
typedef HANDLE(WINAPI* CreateToolhelp32SnapshotType)(DWORD, DWORD);
typedef BOOL(WINAPI* Process32FirstType)(HANDLE, LPPROCESSENTRY32);
typedef BOOL(WINAPI* Process32NextType)(HANDLE, LPPROCESSENTRY32);
typedef NTSTATUS(WINAPI* ZwQuerySystemInformationType)(ULONG, PVOID, ULONG,
                                                       PULONG);

static int kwsysProcess_List__New_NT4(kwsysProcess_List* self);
static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self);
static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self);
static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self);
static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self);
static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self);
static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self);
static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self);
static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self);
static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self);
static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self);
static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self);

struct kwsysProcess_List_s
{
  /* Implementation switches at runtime based on version of Windows.  */
  int NT4;

  /* Implementation functions and data for NT 4.  */
  ZwQuerySystemInformationType P_ZwQuerySystemInformation;
  char* Buffer;
  int BufferSize;
  PSYSTEM_PROCESS_INFORMATION CurrentInfo;

  /* Implementation functions and data for other Windows versions.  */
  CreateToolhelp32SnapshotType P_CreateToolhelp32Snapshot;
  Process32FirstType P_Process32First;
  Process32NextType P_Process32Next;
  HANDLE Snapshot;
  PROCESSENTRY32 CurrentEntry;
};

static kwsysProcess_List* kwsysProcess_List_New(void)
{
  OSVERSIONINFO osv;
  kwsysProcess_List* self;

  /* Allocate and initialize the list object.  */
  if (!(self = (kwsysProcess_List*)malloc(sizeof(kwsysProcess_List)))) {
    return 0;
  }
  memset(self, 0, sizeof(*self));

  /* Select an implementation.  */
  ZeroMemory(&osv, sizeof(osv));
  osv.dwOSVersionInfoSize = sizeof(osv);
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
#  pragma warning(push)
#  ifdef __INTEL_COMPILER
#    pragma warning(disable : 1478)
#  elif defined __clang__
#    pragma clang diagnostic push
#    pragma clang diagnostic ignored "-Wdeprecated-declarations"
#  else
#    pragma warning(disable : 4996)
#  endif
#endif
  GetVersionEx(&osv);
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
#  ifdef __clang__
#    pragma clang diagnostic pop
#  else
#    pragma warning(pop)
#  endif
#endif
  self->NT4 =
    (osv.dwPlatformId == VER_PLATFORM_WIN32_NT && osv.dwMajorVersion < 5) ? 1
                                                                          : 0;

  /* Initialize the selected implementation.  */
  if (!(self->NT4 ? kwsysProcess_List__New_NT4(self)
                  : kwsysProcess_List__New_Snapshot(self))) {
    kwsysProcess_List_Delete(self);
    return 0;
  }

  /* Update to the current set of processes.  */
  if (!kwsysProcess_List_Update(self)) {
    kwsysProcess_List_Delete(self);
    return 0;
  }
  return self;
}

static void kwsysProcess_List_Delete(kwsysProcess_List* self)
{
  if (self) {
    if (self->NT4) {
      kwsysProcess_List__Delete_NT4(self);
    } else {
      kwsysProcess_List__Delete_Snapshot(self);
    }
    free(self);
  }
}

static int kwsysProcess_List_Update(kwsysProcess_List* self)
{
  return self ? (self->NT4 ? kwsysProcess_List__Update_NT4(self)
                           : kwsysProcess_List__Update_Snapshot(self))
              : 0;
}

static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self)
{
  return self ? (self->NT4 ? kwsysProcess_List__GetProcessId_NT4(self)
                           : kwsysProcess_List__GetProcessId_Snapshot(self))
              : -1;
}

static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self)
{
  return self ? (self->NT4 ? kwsysProcess_List__GetParentId_NT4(self)
                           : kwsysProcess_List__GetParentId_Snapshot(self))
              : -1;
}

static int kwsysProcess_List_NextProcess(kwsysProcess_List* self)
{
  return (self ? (self->NT4 ? kwsysProcess_List__Next_NT4(self)
                            : kwsysProcess_List__Next_Snapshot(self))
               : 0);
}

static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
{
  /* Get a handle to the NT runtime module that should already be
     loaded in this program.  This does not actually increment the
     reference count to the module so we do not need to close the
     handle.  */
  HMODULE hNT = GetModuleHandleW(L"ntdll.dll");
  if (hNT) {
    /* Get pointers to the needed API functions.  */
    self->P_ZwQuerySystemInformation =
      ((ZwQuerySystemInformationType)GetProcAddress(
        hNT, "ZwQuerySystemInformation"));
  }
  if (!self->P_ZwQuerySystemInformation) {
    return 0;
  }

  /* Allocate an initial process information buffer.  */
  self->BufferSize = 32768;
  self->Buffer = (char*)malloc(self->BufferSize);
  return self->Buffer ? 1 : 0;
}

static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self)
{
  /* Free the process information buffer.  */
  free(self->Buffer);
}

static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self)
{
  self->CurrentInfo = 0;
  for (;;) {
    /* Query number 5 is for system process list.  */
    NTSTATUS status =
      self->P_ZwQuerySystemInformation(5, self->Buffer, self->BufferSize, 0);
    if (status == STATUS_INFO_LENGTH_MISMATCH) {
      /* The query requires a bigger buffer.  */
      int newBufferSize = self->BufferSize * 2;
      char* newBuffer = (char*)malloc(newBufferSize);
      if (newBuffer) {
        free(self->Buffer);
        self->Buffer = newBuffer;
        self->BufferSize = newBufferSize;
      } else {
        return 0;
      }
    } else if (status >= 0) {
      /* The query succeeded.  Initialize traversal of the process list.  */
      self->CurrentInfo = (PSYSTEM_PROCESS_INFORMATION)self->Buffer;
      return 1;
    } else {
      /* The query failed.  */
      return 0;
    }
  }
}

static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self)
{
  if (self->CurrentInfo) {
    if (self->CurrentInfo->NextEntryDelta > 0) {
      self->CurrentInfo = ((PSYSTEM_PROCESS_INFORMATION)(
        (char*)self->CurrentInfo + self->CurrentInfo->NextEntryDelta));
      return 1;
    }
    self->CurrentInfo = 0;
  }
  return 0;
}

static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self)
{
  return self->CurrentInfo ? self->CurrentInfo->ProcessId : -1;
}

static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self)
{
  return self->CurrentInfo ? self->CurrentInfo->InheritedFromProcessId : -1;
}

static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self)
{
  /* Get a handle to the Windows runtime module that should already be
     loaded in this program.  This does not actually increment the
     reference count to the module so we do not need to close the
     handle.  */
  HMODULE hKernel = GetModuleHandleW(L"kernel32.dll");
  if (hKernel) {
    self->P_CreateToolhelp32Snapshot =
      ((CreateToolhelp32SnapshotType)GetProcAddress(
        hKernel, "CreateToolhelp32Snapshot"));
    self->P_Process32First =
      ((Process32FirstType)GetProcAddress(hKernel, "Process32First"));
    self->P_Process32Next =
      ((Process32NextType)GetProcAddress(hKernel, "Process32Next"));
  }
  return (self->P_CreateToolhelp32Snapshot && self->P_Process32First &&
          self->P_Process32Next)
    ? 1
    : 0;
}

static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self)
{
  if (self->Snapshot) {
    CloseHandle(self->Snapshot);
  }
}

static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self)
{
  if (self->Snapshot) {
    CloseHandle(self->Snapshot);
  }
  if (!(self->Snapshot =
          self->P_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0))) {
    return 0;
  }
  ZeroMemory(&self->CurrentEntry, sizeof(self->CurrentEntry));
  self->CurrentEntry.dwSize = sizeof(self->CurrentEntry);
  if (!self->P_Process32First(self->Snapshot, &self->CurrentEntry)) {
    CloseHandle(self->Snapshot);
    self->Snapshot = 0;
    return 0;
  }
  return 1;
}

static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self)
{
  if (self->Snapshot) {
    if (self->P_Process32Next(self->Snapshot, &self->CurrentEntry)) {
      return 1;
    }
    CloseHandle(self->Snapshot);
    self->Snapshot = 0;
  }
  return 0;
}

static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self)
{
  return self->Snapshot ? self->CurrentEntry.th32ProcessID : -1;
}

static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self)
{
  return self->Snapshot ? self->CurrentEntry.th32ParentProcessID : -1;
}

static void kwsysProcessKill(DWORD pid)
{
  HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, pid);
  if (h) {
    TerminateProcess(h, 255);
    WaitForSingleObject(h, INFINITE);
    CloseHandle(h);
  }
}

static void kwsysProcessKillTree(int pid)
{
  kwsysProcess_List* plist = kwsysProcess_List_New();
  kwsysProcessKill(pid);
  if (plist) {
    do {
      if (kwsysProcess_List_GetCurrentParentId(plist) == pid) {
        int ppid = kwsysProcess_List_GetCurrentProcessId(plist);
        kwsysProcessKillTree(ppid);
      }
    } while (kwsysProcess_List_NextProcess(plist));
    kwsysProcess_List_Delete(plist);
  }
}

static void kwsysProcessDisablePipeThreads(kwsysProcess* cp)
{
  int i;

  /* If data were just reported data, release the pipe's thread.  */
  if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) {
    KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
    ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
    cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
  }

  /* Wakeup all reading threads that are not on closed pipes.  */
  for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
    /* The wakeup threads will write one byte to the pipe write ends.
       If there are no data in the pipe then this is enough to wakeup
       the reading threads.  If there are already data in the pipe
       this may block.  We cannot use PeekNamedPipe to check whether
       there are data because an outside process might still be
       writing data if we are disowning it.  Also, PeekNamedPipe will
       block if checking a pipe on which the reading thread is
       currently calling ReadPipe.  Therefore we need a separate
       thread to call WriteFile.  If it blocks, that is okay because
       it will unblock when we close the read end and break the pipe
       below.  */
    if (cp->Pipe[i].Read) {
      KWSYSPE_DEBUG((stderr, "releasing waker %d\n", i));
      ReleaseSemaphore(cp->Pipe[i].Waker.Go, 1, 0);
    }
  }

  /* Tell pipe threads to reset until we run another process.  */
  while (cp->PipesLeft > 0) {
    /* The waking threads will cause all reading threads to report.
       Wait for the next one and save its index.  */
    KWSYSPE_DEBUG((stderr, "waiting for reader\n"));
    WaitForSingleObject(cp->Full, INFINITE);
    cp->CurrentIndex = cp->SharedIndex;
    ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);
    KWSYSPE_DEBUG((stderr, "got reader %d\n", cp->CurrentIndex));

    /* We are done reading this pipe.  Close its read handle.  */
    cp->Pipe[cp->CurrentIndex].Closed = 1;
    kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read);
    --cp->PipesLeft;

    /* Tell the reading thread we are done with the data.  It will
       reset immediately because the pipe is closed.  */
    ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
  }
}

/* Global set of executing processes for use by the Ctrl handler.
   This global instance will be zero-initialized by the compiler.

   Note that the console Ctrl handler runs on a background thread and so
   everything it does must be thread safe.  Here, we track the hProcess
   HANDLEs directly instead of kwsysProcess instances, so that we don't have
   to make kwsysProcess thread safe.  */
typedef struct kwsysProcessInstance_s
{
  HANDLE hProcess;
  DWORD dwProcessId;
  int NewProcessGroup; /* Whether the process was created in a new group.  */
} kwsysProcessInstance;

typedef struct kwsysProcessInstances_s
{
  /* Whether we have initialized key fields below, like critical sections.  */
  int Initialized;

  /* Ctrl handler runs on a different thread, so we must sync access.  */
  CRITICAL_SECTION Lock;

  int Exiting;
  size_t Count;
  size_t Size;
  kwsysProcessInstance* Processes;
} kwsysProcessInstances;
static kwsysProcessInstances kwsysProcesses;

/* Initialize critial section and set up console Ctrl handler.  You MUST call
   this before using any other kwsysProcesses* functions below.  */
static int kwsysProcessesInitialize(void)
{
  /* Initialize everything if not done already.  */
  if (!kwsysProcesses.Initialized) {
    InitializeCriticalSection(&kwsysProcesses.Lock);

    /* Set up console ctrl handler.  */
    if (!SetConsoleCtrlHandler(kwsysCtrlHandler, TRUE)) {
      return 0;
    }

    kwsysProcesses.Initialized = 1;
  }
  return 1;
}

/* The Ctrl handler waits on the global list of processes.  To prevent an
   orphaned process, do not create a new process if the Ctrl handler is
   already running.  Do so by using this function to check if it is ok to
   create a process.  */
static int kwsysTryEnterCreateProcessSection(void)
{
  /* Enter main critical section; this means creating a process and the Ctrl
     handler are mutually exclusive.  */
  EnterCriticalSection(&kwsysProcesses.Lock);
  /* Indicate to the caller if they can create a process.  */
  if (kwsysProcesses.Exiting) {
    LeaveCriticalSection(&kwsysProcesses.Lock);
    return 0;
  } else {
    return 1;
  }
}

/* Matching function on successful kwsysTryEnterCreateProcessSection return.
   Make sure you called kwsysProcessesAdd if applicable before calling this.*/
static void kwsysLeaveCreateProcessSection(void)
{
  LeaveCriticalSection(&kwsysProcesses.Lock);
}

/* Add new process to global process list.  The Ctrl handler will wait for
   the process to exit before it returns.  Do not close the process handle
   until after calling kwsysProcessesRemove.  The newProcessGroup parameter
   must be set if the process was created with CREATE_NEW_PROCESS_GROUP.  */
static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessid,
                             int newProcessGroup)
{
  if (!kwsysProcessesInitialize() || !hProcess ||
      hProcess == INVALID_HANDLE_VALUE) {
    return 0;
  }

  /* Enter the critical section. */
  EnterCriticalSection(&kwsysProcesses.Lock);

  /* Make sure there is enough space for the new process handle.  */
  if (kwsysProcesses.Count == kwsysProcesses.Size) {
    size_t newSize;
    kwsysProcessInstance* newArray;
    /* Start with enough space for a small number of process handles
       and double the size each time more is needed.  */
    newSize = kwsysProcesses.Size ? kwsysProcesses.Size * 2 : 4;

    /* Try allocating the new block of memory.  */
    if ((newArray = (kwsysProcessInstance*)malloc(
           newSize * sizeof(kwsysProcessInstance)))) {
      /* Copy the old process handles to the new memory.  */
      if (kwsysProcesses.Count > 0) {
        memcpy(newArray, kwsysProcesses.Processes,
               kwsysProcesses.Count * sizeof(kwsysProcessInstance));
      }
    } else {
      /* Failed to allocate memory for the new process handle set.  */
      LeaveCriticalSection(&kwsysProcesses.Lock);
      return 0;
    }

    /* Free original array. */
    free(kwsysProcesses.Processes);

    /* Update original structure with new allocation. */
    kwsysProcesses.Size = newSize;
    kwsysProcesses.Processes = newArray;
  }

  /* Append the new process information to the set.  */
  kwsysProcesses.Processes[kwsysProcesses.Count].hProcess = hProcess;
  kwsysProcesses.Processes[kwsysProcesses.Count].dwProcessId = dwProcessid;
  kwsysProcesses.Processes[kwsysProcesses.Count++].NewProcessGroup =
    newProcessGroup;

  /* Leave critical section and return success. */
  LeaveCriticalSection(&kwsysProcesses.Lock);

  return 1;
}

/* Removes process to global process list.  */
static void kwsysProcessesRemove(HANDLE hProcess)
{
  size_t i;

  if (!hProcess || hProcess == INVALID_HANDLE_VALUE) {
    return;
  }

  EnterCriticalSection(&kwsysProcesses.Lock);

  /* Find the given process in the set.  */
  for (i = 0; i < kwsysProcesses.Count; ++i) {
    if (kwsysProcesses.Processes[i].hProcess == hProcess) {
      break;
    }
  }
  if (i < kwsysProcesses.Count) {
    /* Found it!  Remove the process from the set.  */
    --kwsysProcesses.Count;
    for (; i < kwsysProcesses.Count; ++i) {
      kwsysProcesses.Processes[i] = kwsysProcesses.Processes[i + 1];
    }

    /* If this was the last process, free the array.  */
    if (kwsysProcesses.Count == 0) {
      kwsysProcesses.Size = 0;
      free(kwsysProcesses.Processes);
      kwsysProcesses.Processes = 0;
    }
  }

  LeaveCriticalSection(&kwsysProcesses.Lock);
}

static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType)
{
  size_t i;
  (void)dwCtrlType;
  /* Enter critical section.  */
  EnterCriticalSection(&kwsysProcesses.Lock);

  /* Set flag indicating that we are exiting.  */
  kwsysProcesses.Exiting = 1;

  /* If some of our processes were created in a new process group, we must
     manually interrupt them.  They won't otherwise receive a Ctrl+C/Break. */
  for (i = 0; i < kwsysProcesses.Count; ++i) {
    if (kwsysProcesses.Processes[i].NewProcessGroup) {
      DWORD groupId = kwsysProcesses.Processes[i].dwProcessId;
      if (groupId) {
        GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, groupId);
      }
    }
  }

  /* Wait for each child process to exit.  This is the key step that prevents
     us from leaving several orphaned children processes running in the
     background when the user presses Ctrl+C.  */
  for (i = 0; i < kwsysProcesses.Count; ++i) {
    WaitForSingleObject(kwsysProcesses.Processes[i].hProcess, INFINITE);
  }

  /* Leave critical section.  */
  LeaveCriticalSection(&kwsysProcesses.Lock);

  /* Continue on to default Ctrl handler (which calls ExitProcess).  */
  return FALSE;
}

void kwsysProcess_ResetStartTime(kwsysProcess* cp)
{
  if (!cp) {
    return;
  }
  /* Reset start time. */
  cp->StartTime = kwsysProcessTimeGetCurrent();
}
