/* 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>  /* sprintf */
#include <string.h> /* strlen, strdup */
#ifdef __WATCOMC__
#  define _unlink unlink
#endif

#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

#if defined(__BORLANDC__)
#  pragma warn - 8004 /* assigned a value that is never used  */
#  pragma warn - 8060 /* Assignment inside if() condition.  */
#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, 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;
    }
    SetCurrentDirectoryW(cp->WorkingDirectory);
  }

  /* 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%X.  "
                  "FormatMessage failed with error 0x%X",
                  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%X.  "
                  "WideCharToMultiByte failed with error 0x%X",
                  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 hanlde");
      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();
}
