diff --git a/ProcessUNIX.c b/ProcessUNIX.c
index 48b8eb15d6c8ac6bdcbaa9496ab2f67adbe9cd36..60f6b24b7340064c7bc25303fe81b471095f48f7 100644
--- a/ProcessUNIX.c
+++ b/ProcessUNIX.c
@@ -46,23 +46,35 @@ timeout for program even when it closes stdout and stderr.
 #include <signal.h>    /* sigaction */
 
 /* The number of pipes for the child's output.  The standard stdout
-   and stderr pipes are the first two.  One more pipe is used for the
-   child to report errors to the parent before the real process is
-   invoked.  */
+   and stderr pipes are the first two.  One more pipe is used to
+   detect when the child process has terminated.  The third pipe is
+   not given to the child process, so it cannot close it until it
+   terminates.  */
 #define KWSYSPE_PIPE_COUNT 3
 #define KWSYSPE_PIPE_STDOUT 0
 #define KWSYSPE_PIPE_STDERR 1
-#define KWSYSPE_PIPE_ERROR 2
+#define KWSYSPE_PIPE_TERM 2
 
 /* The maximum amount to read from a pipe at a time.  */
 #define KWSYSPE_PIPE_BUFFER_SIZE 1024
 
 typedef struct timeval kwsysProcessTime;
 
+typedef struct kwsysProcessCreateInformation_s
+{
+  int stdin;
+  int stdout;
+  int stderr;
+  int term;
+  int error[2];
+} kwsysProcessCreateInformation;
+
 /*--------------------------------------------------------------------------*/
-static void kwsysProcessInitialize(kwsysProcess* cp);
+static int kwsysProcessInitialize(kwsysProcess* cp);
 static void kwsysProcessCleanup(kwsysProcess* cp, int error);
 static void kwsysProcessCleanupDescriptor(int* pfd);
+static int kwsysProcessCreate(kwsysProcess* cp, int index,
+                              kwsysProcessCreateInformation* si, int* readEnd);
 static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
                                       kwsysProcessTime* timeoutTime);
 static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
@@ -73,7 +85,7 @@ 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 kwsysProcessChildErrorExit(kwsysProcess* cp);
+static void kwsysProcessChildErrorExit(int errorPipe);
 static void kwsysProcessRestoreDefaultSignalHandlers();
 
 /*--------------------------------------------------------------------------*/
@@ -87,17 +99,14 @@ struct kwsysProcess_s
   /* Descriptors for the read ends of the child's output pipes. */
   int PipeReadEnds[KWSYSPE_PIPE_COUNT];
 
-  /* Descriptors for the write ends of the child's output pipes. */
-  int PipeWriteEnds[KWSYSPE_PIPE_COUNT];
-
   /* Buffer for pipe data.  */
   char PipeBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
 
-  /* Process ID returned by the fork.  */
-  pid_t ForkPID;
+  /* Process IDs returned by the calls to fork.  */
+  pid_t* ForkPIDs;
 
-  /* Flag for whether the child reported an error.  */
-  int ChildError;
+  /* Flag for whether the children were terminated by a faild select.  */
+  int SelectError;
 
   /* The timeout length.  */
   double Timeout;
@@ -141,7 +150,9 @@ struct kwsysProcess_s
 
   /* Buffer for error message in case of failure.  */
   char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
-  int ErrorMessageLength;
+
+  /* The exit codes of each child process in the pipeline.  */
+  int* CommandExitCodes;
 };
 
 /*--------------------------------------------------------------------------*/
@@ -170,6 +181,10 @@ void kwsysProcess_Delete(kwsysProcess* cp)
   /* Free memory.  */
   kwsysProcess_SetCommand(cp, 0);
   kwsysProcess_SetWorkingDirectory(cp, 0);
+  if(cp->CommandExitCodes)
+    {
+    free(cp->CommandExitCodes);
+    }
   free(cp);
 }
 
@@ -359,6 +374,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
 {
   int i;
   struct sigaction newSigChldAction;
+  kwsysProcessCreateInformation si = {-1, -1, -1, -1, {-1, -1}};
 
   /* Do not execute a second copy simultaneously.  */
   if(cp->State == kwsysProcess_State_Executing)
@@ -367,7 +383,12 @@ void kwsysProcess_Execute(kwsysProcess* cp)
     }
 
   /* Initialize the control structure for a new process.  */
-  kwsysProcessInitialize(cp);
+  if(!kwsysProcessInitialize(cp))
+    {
+    strcpy(cp->ErrorMessage, "Out of memory");
+    cp->State = kwsysProcess_State_Error;
+    return;
+    }
 
   /* We want no special handling of SIGCHLD.  Repeat call until it is
      not interrupted.  */
@@ -376,29 +397,37 @@ void kwsysProcess_Execute(kwsysProcess* cp)
   while((sigaction(SIGCHLD, &newSigChldAction, &cp->OldSigChldAction) < 0) &&
         (errno == EINTR));
 
-  /* Create pipes for subprocess output.  */
-  for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+  /* Setup the stderr and termination pipes to be shared by all processes.  */
+  for(i=KWSYSPE_PIPE_STDERR; i < KWSYSPE_PIPE_COUNT; ++i)
     {
-    int p[2];
-
     /* Create the pipe.  */
+    int p[2];
     if(pipe(p) < 0)
       {
       kwsysProcessCleanup(cp, 1);
       return;
       }
 
+    /* Store the pipe.  */
+    cp->PipeReadEnds[i] = p[0];
+    if(i == KWSYSPE_PIPE_STDERR)
+      {
+      si.stderr = p[1];
+      }
+    else
+      {
+      si.term = p[1];
+      }
+
     /* Set close-on-exec flag on the pipe's ends.  */
     if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
        (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
       {
       kwsysProcessCleanup(cp, 1);
+      kwsysProcessCleanupDescriptor(&si.stderr);
+      kwsysProcessCleanupDescriptor(&si.term);
       return;
       }
-
-    /* Store the pipe.  */
-    cp->PipeReadEnds[i] = p[0];
-    cp->PipeWriteEnds[i] = p[1];
     }
 
   /* The timeout period starts now.  */
@@ -406,62 +435,37 @@ void kwsysProcess_Execute(kwsysProcess* cp)
   cp->TimeoutTime.tv_sec = -1;
   cp->TimeoutTime.tv_usec = -1;
 
-  /* Fork off a child process.  */
-  cp->ForkPID = fork();
-  if(cp->ForkPID < 0)
-    {
-    kwsysProcessCleanup(cp, 1);
-    return;
-    }
-
-  /* If this is the child process, run the real process.  */
-  if(cp->ForkPID == 0)
+  /* Create the pipeline of processes.  */
+  {
+  int readEnd = 0;
+  for(i=0; i < cp->NumberOfCommands; ++i)
     {
-    /* We used to close stdin, but some programs do not like being run
-       without stdin.  Just use whatever stdin the parent program is
-       using.  */
-    /*close(0);*/
-
-    /* Setup the stdout/stderr pipes.  */
-    dup2(cp->PipeWriteEnds[KWSYSPE_PIPE_STDOUT], 1);
-    dup2(cp->PipeWriteEnds[KWSYSPE_PIPE_STDERR], 2);
-
-    /* Clear the close-on-exec flag for stdout, stderr, and the child
-       error report pipe.  All other pipe handles will be closed when
-       exec succeeds.  */
-    fcntl(1, F_SETFD, 0);
-    fcntl(2, F_SETFD, 0);
-    fcntl(cp->PipeWriteEnds[KWSYSPE_PIPE_ERROR], F_SETFD, 0);
-
-    /* Restore all default signal handlers. */
-    kwsysProcessRestoreDefaultSignalHandlers();
-
-    /* Change to the working directory specified, if any.  */
-    if(cp->WorkingDirectory)
+    if(!kwsysProcessCreate(cp, i, &si, &readEnd))
       {
-      /* Some platforms specify that the chdir call may be
-         interrupted.  Repeat the call until it finishes.  */
-      int r;
-      while(((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR));
-      if(r < 0)
+      kwsysProcessCleanup(cp, 1);
+
+      /* Release resources that may have been allocated for this
+         process before an error occurred.  */
+      kwsysProcessCleanupDescriptor(&readEnd);
+      if(i > 0)
         {
-        /* Failure.  Report error to parent and terminate.  */
-        kwsysProcessChildErrorExit(cp);
+        kwsysProcessCleanupDescriptor(&si.stdin);
         }
+      kwsysProcessCleanupDescriptor(&si.stdout);
+      kwsysProcessCleanupDescriptor(&si.stderr);
+      kwsysProcessCleanupDescriptor(&si.term);
+      kwsysProcessCleanupDescriptor(&si.error[0]);
+      kwsysProcessCleanupDescriptor(&si.error[1]);
+      return;
       }
-
-    /* Execute the real process.  If successful, this does not return.  */
-    execvp(cp->Command[0], cp->Command);
-
-    /* Failure.  Report error to parent and terminate.  */
-    kwsysProcessChildErrorExit(cp);
     }
+  /* Save a handle to the output pipe for the last process.  */
+  cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = readEnd;
+  }
 
-  /* The parent process does not need the pipe write ends.  */
-  for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
-    {
-    kwsysProcessCleanupDescriptor(&cp->PipeWriteEnds[i]);
-    }
+  /* The parent process does not need the output pipe write ends.  */
+  kwsysProcessCleanupDescriptor(&si.stderr);
+  kwsysProcessCleanupDescriptor(&si.term);
 
   /* All the pipes are now open.  */
   cp->PipesLeft = KWSYSPE_PIPE_COUNT;
@@ -518,22 +522,9 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data,
         if(n > 0)
           {
           /* We have data on this pipe.  */
-          if(i == KWSYSPE_PIPE_ERROR)
+          if(i == KWSYSPE_PIPE_TERM)
             {
-            /* This is data on the special error reporting pipe.  The
-               child process failed to execute the program.  */
-            cp->ChildError = 1;
-            if(n > KWSYSPE_PIPE_BUFFER_SIZE - cp->ErrorMessageLength)
-              {
-              n = KWSYSPE_PIPE_BUFFER_SIZE - cp->ErrorMessageLength;
-              }
-            if(n > 0)
-              {
-              memcpy(cp->ErrorMessage+cp->ErrorMessageLength,
-                     cp->PipeBuffer, n);
-              cp->ErrorMessageLength += n;
-              cp->ErrorMessage[cp->ErrorMessageLength] = 0;
-              }
+            /* This is data on the special termination pipe.  Ignore it.  */
             }
           else if(pipes & (1 << i))
             {
@@ -618,10 +609,10 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data,
          pipe buffer.  */
       strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
 
-      /* Kill the child now.  */
+      /* Kill the children now.  */
       kwsysProcess_Kill(cp);
       cp->Killed = 0;
-      cp->ChildError = 1;
+      cp->SelectError = 1;
       cp->PipesLeft = 0;
       }
     }
@@ -656,7 +647,7 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data,
       }
     else
       {
-      /* The process timeout has expired.  Kill the child now.  */
+      /* The process timeout has expired.  Kill the children now.  */
       kwsysProcess_Kill(cp);
       cp->Killed = 0;
       cp->TimeoutExpired = 1;
@@ -693,19 +684,36 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
       }
     }
 
-  /* Wait for the child to terminate.  The process should have already
-     exited because KWSYSPE_PIPE_ERROR has been closed by this point.
-     Repeat the call until it is not interrupted.  */
-  while(((result = waitpid(cp->ForkPID, &status, 0)) < 0) && (errno == EINTR));
-  if(result <= 0)
+  /* Wait for each child to terminate.  The process should have
+     already exited because KWSYSPE_PIPE_TERM has been closed by this
+     point.  Repeat the call until it is not interrupted.  */
+  {
+  int i;
+  for(i=0; i < cp->NumberOfCommands; ++i)
+    {
+    while(((result = waitpid(cp->ForkPIDs[i],
+                             &cp->CommandExitCodes[i], 0)) < 0) &&
+          (errno == EINTR));
+    if(result <= 0 && cp->State != kwsysProcess_State_Error)
+      {
+      /* Unexpected error.  Report the first time this happens.  */
+      strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+      cp->State = kwsysProcess_State_Error;
+      }
+    }
+  }
+
+  /* Check if there was an error in one of the waitpid calls.  */
+  if(cp->State == kwsysProcess_State_Error)
     {
-    /* Unexpected error.  */
-    kwsysProcessCleanup(cp, 1);
+    /* The error message is already in its buffer.  Tell
+       kwsysProcessCleanup to not create it.  */
+    kwsysProcessCleanup(cp, 0);
     return 1;
     }
 
   /* Check whether the child reported an error invoking the process.  */
-  if(cp->ChildError)
+  if(cp->SelectError)
     {
     /* The error message is already in its buffer.  Tell
        kwsysProcessCleanup to not create it.  */
@@ -714,6 +722,9 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
     return 1;
     }
 
+  /* Use the status of the last process in the pipeline.  */
+  status = cp->CommandExitCodes[cp->NumberOfCommands-1];
+
   /* Determine the outcome.  */
   if(cp->Killed)
     {
@@ -773,29 +784,35 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
 /*--------------------------------------------------------------------------*/
 void kwsysProcess_Kill(kwsysProcess* cp)
 {
+  int i;
+
   /* Make sure we are executing a process.  */
   if(cp->State != kwsysProcess_State_Executing)
     {
     return;
     }
 
-  /* Kill the child.  */
+  /* Kill the children.  */
   cp->Killed = 1;
-  kill(cp->ForkPID, SIGKILL);
+  for(i=0; i < cp->NumberOfCommands; ++i)
+    {
+    if(cp->ForkPIDs[i])
+      {
+      kill(cp->ForkPIDs[i], SIGKILL);
+      }
+    }
 }
 
 /*--------------------------------------------------------------------------*/
 /* Initialize a process control structure for kwsysProcess_Execute.  */
-static void kwsysProcessInitialize(kwsysProcess* cp)
+static int kwsysProcessInitialize(kwsysProcess* cp)
 {
   int i;
   for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
     {
     cp->PipeReadEnds[i] = -1;
-    cp->PipeWriteEnds[i] = -1;
     }
-  cp->ForkPID = -1;
-  cp->ChildError = 0;
+  cp->SelectError = 0;
   cp->StartTime.tv_sec = -1;
   cp->StartTime.tv_usec = -1;
   cp->TimeoutTime.tv_sec = -1;
@@ -809,7 +826,30 @@ static void kwsysProcessInitialize(kwsysProcess* cp)
   cp->ExitCode = 1;
   cp->ExitValue = 1;
   cp->ErrorMessage[0] = 0;
-  cp->ErrorMessageLength = 0;
+
+  if(cp->ForkPIDs)
+    {
+    free(cp->ForkPIDs);
+    }
+  cp->ForkPIDs = (pid_t*)malloc(sizeof(pid_t)*cp->NumberOfCommands);
+  if(!cp->ForkPIDs)
+    {
+    return 0;
+    }
+  memset(cp->ForkPIDs, 0, sizeof(pid_t)*cp->NumberOfCommands);
+
+  if(cp->CommandExitCodes)
+    {
+    free(cp->CommandExitCodes);
+    }
+  cp->CommandExitCodes = (int*)malloc(sizeof(int)*cp->NumberOfCommands);
+  if(!cp->CommandExitCodes)
+    {
+    return 0;
+    }
+  memset(cp->CommandExitCodes, 0, sizeof(int)*cp->NumberOfCommands);
+
+  return 1;
 }
 
 /*--------------------------------------------------------------------------*/
@@ -819,22 +859,46 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error)
 {
   int i;
 
-  /* If cleaning up due to an error, report the error message.  */
   if(error)
     {
-    strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+    /* We are cleaning up due to an error.  Report the error message
+       if one has not been provided already.  */
+    if(cp->ErrorMessage[0] == 0)
+      {
+      strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+      }
+
+    /* Set the error state.  */
     cp->State = kwsysProcess_State_Error;
+
+    /* Kill any children already started.  */
+    if(cp->ForkPIDs)
+      {
+      for(i=0; i < cp->NumberOfCommands; ++i)
+        {
+        if(cp->ForkPIDs[i])
+          {
+          kill(cp->ForkPIDs[i], SIGKILL);
+          }
+        }
+      }
     }
 
   /* Restore the SIGCHLD handler.  */
   while((sigaction(SIGCHLD, &cp->OldSigChldAction, 0) < 0) &&
         (errno == EINTR));
 
+  /* Free memory.  */
+  if(cp->ForkPIDs)
+    {
+    free(cp->ForkPIDs);
+    cp->ForkPIDs = 0;
+    }
+
   /* Close pipe handles.  */
   for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
     {
     kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
-    kwsysProcessCleanupDescriptor(&cp->PipeWriteEnds[i]);
     }
 }
 
@@ -851,6 +915,137 @@ static void kwsysProcessCleanupDescriptor(int* pfd)
     }
 }
 
+/*--------------------------------------------------------------------------*/
+int kwsysProcessCreate(kwsysProcess* cp, int index,
+                       kwsysProcessCreateInformation* si, int* readEnd)
+{
+  /* Setup the process's stdin.  */
+  if(index > 0)
+    {
+    si->stdin = *readEnd;
+    *readEnd = 0;
+    }
+  else
+    {
+    si->stdin = 0;
+    }
+
+  /* Setup the process's stdout.  */
+  {
+  /* Create the pipe.  */
+  int p[2];
+  if(pipe(p) < 0)
+    {
+    return 0;
+    }
+  *readEnd = p[0];
+  si->stdout = p[1];
+
+  /* Set close-on-exec flag on the pipe's ends.  */
+  if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
+     (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
+    {
+    return 0;
+    }
+  }
+
+  /* Create the error reporting pipe.  */
+  if(pipe(si->error) < 0)
+    {
+    return 0;
+    }
+
+  /* Set close-on-exec flag on the error pipe's write end.  */
+  if(fcntl(si->error[1], F_SETFD, FD_CLOEXEC) < 0)
+    {
+    return 0;
+    }
+
+  /* Fork off a child process.  */
+  cp->ForkPIDs[index] = fork();
+  if(cp->ForkPIDs[index] < 0)
+    {
+    return 0;
+    }
+
+  if(cp->ForkPIDs[index] == 0)
+    {
+    /* Close the read end of the error reporting pipe.  */
+    close(si->error[0]);
+
+    /* Setup the stdin, stdout, and stderr pipes.  */
+    if(index > 0)
+      {
+      dup2(si->stdin, 0);
+      }
+    dup2(si->stdout, 1);
+    dup2(si->stderr, 2);
+
+    /* Clear the close-on-exec flag for stdin, stdout, and stderr.
+       Also clear it for the termination pipe.  All other pipe handles
+       will be closed when exec succeeds.  */
+    fcntl(0, F_SETFD, 0);
+    fcntl(1, F_SETFD, 0);
+    fcntl(2, F_SETFD, 0);
+    fcntl(si->term, F_SETFD, 0);
+
+    /* Restore all default signal handlers. */
+    kwsysProcessRestoreDefaultSignalHandlers();
+
+    /* Change to the working directory specified, if any.  */
+    if(cp->WorkingDirectory)
+      {
+      /* Some platforms specify that the chdir call may be
+         interrupted.  Repeat the call until it finishes.  */
+      int r;
+      while(((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR));
+      if(r < 0)
+        {
+        /* Failure.  Report error to parent and terminate.  */
+        kwsysProcessChildErrorExit(si->error[1]);
+        }
+      }
+
+    /* Execute the real process.  If successful, this does not return.  */
+    execvp(cp->Commands[index][0], cp->Commands[index]);
+
+    /* Failure.  Report error to parent and terminate.  */
+    kwsysProcessChildErrorExit(si->error[1]);
+    }
+
+  /* Close the write end of the error pipe.  */
+  close(si->error[1]);
+  si->error[1] = 0;
+
+  /* Block until the child's exec call succeeds and closes the error
+     pipe or writes data to the pipe to report an error.  */
+  {
+  int n;
+  /* Keep trying to read until the operation is not interrupted.  */
+  while(((n = read(si->error[0], cp->ErrorMessage,
+                   KWSYSPE_PIPE_BUFFER_SIZE)) < 0) && (errno == EINTR));
+  close(si->error[0]);
+  si->error[0] = 0;
+  if(n > 0)
+    {
+    /* The child failed to execute the process.  */
+    return 0;
+    }
+  }
+
+  /* Successfully created this child process.  */
+  if(index > 0)
+    {
+    /* The parent process does not need the input pipe read end.  */
+    kwsysProcessCleanupDescriptor(&si->stdin);
+    }
+
+  /* The parent process does not need the output pipe write ends.  */
+  kwsysProcessCleanupDescriptor(&si->stdout);
+
+  return 1;
+}
+
 /*--------------------------------------------------------------------------*/
 /* Get the time at which either the process or user timeout will
    expire.  Returns 1 if the user timeout is first, and 0 otherwise.  */
@@ -975,14 +1170,14 @@ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProc
 /* When the child process encounters an error before its program is
    invoked, this is called to report the error to the parent and
    exit.  */
-static void kwsysProcessChildErrorExit(kwsysProcess* cp)
+static void kwsysProcessChildErrorExit(int errorPipe)
 {
   /* Construct the error message.  */
   char buffer[KWSYSPE_PIPE_BUFFER_SIZE];
   strncpy(buffer, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
 
   /* Report the error to the parent through the special pipe.  */
-  write(cp->PipeWriteEnds[KWSYSPE_PIPE_ERROR], buffer, strlen(buffer));
+  write(errorPipe, buffer, strlen(buffer));
 
   /* Terminate without cleanup.  */
   _exit(1);