diff --git a/ProcessWin32.c b/ProcessWin32.c
index 1f45f66cfa55732170266f4784e4c683aadf7be9..3f2492f83b89bd5f9a21612498fae5b08a030072 100644
--- a/ProcessWin32.c
+++ b/ProcessWin32.c
@@ -49,11 +49,15 @@ Q190351 and Q150956.
 #pragma warning (disable: 4706)
 #endif
 
-/* The whole child pipeline will have one standard output and one
-   standard error.  */
-#define KWSYSPE_PIPE_COUNT 2
+/* The number of pipes for the child's output.  The standard stdout
+   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_TERM 2
 
 /* The maximum amount to read from a pipe at a time.  */
 #define KWSYSPE_PIPE_BUFFER_SIZE 1024
@@ -62,12 +66,22 @@ Q190351 and Q150956.
 
 typedef LARGE_INTEGER kwsysProcessTime;
 
+typedef struct kwsysProcessCreateInformation_s
+{
+  /* Windows child startup control data.  */
+  STARTUPINFO StartupInfo;
+
+  /* Inherited pipe handles.  */
+  HANDLE InheritedWrite[KWSYSPE_PIPE_COUNT];
+} kwsysProcessCreateInformation;
+
 /*--------------------------------------------------------------------------*/
 typedef struct kwsysProcessPipeData_s kwsysProcessPipeData;
 static DWORD WINAPI kwsysProcessPipeThread(LPVOID ptd);
 static void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td);
 static int kwsysProcessInitialize(kwsysProcess* cp);
-static int kwsysProcessCreate(kwsysProcess* cp, int index, STARTUPINFO* si,
+static int kwsysProcessCreate(kwsysProcess* cp, int index,
+                              kwsysProcessCreateInformation* si,
                               PHANDLE readEnd);
 static void kwsysProcessDestroy(kwsysProcess* cp, int event);
 static void kwsysProcessCleanupHandle(PHANDLE h);
@@ -252,7 +266,7 @@ kwsysProcess* kwsysProcess_New()
   ZeroMemory(&osv, sizeof(osv));
   osv.dwOSVersionInfoSize = sizeof(osv);
   GetVersionEx(&osv);
-  if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+  if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS || 1)
     {
     /* This is Win9x.  We need the console forwarding executable to
        work-around a Windows 9x bug.  */
@@ -769,8 +783,8 @@ void kwsysProcess_Execute(kwsysProcess* cp)
 {
   int i;
 
-  /* Windows child startup control data.  */
-  STARTUPINFO si;
+  /* Child startup control data.  */
+  kwsysProcessCreateInformation si;
   
   /* Do not execute a second time.  */
   if(cp->State == kwsysProcess_State_Executing)
@@ -803,37 +817,53 @@ void kwsysProcess_Execute(kwsysProcess* cp)
 
   /* Initialize startup info data.  */
   ZeroMemory(&si, sizeof(si));
-  si.cb = sizeof(si);
+  si.StartupInfo.cb = sizeof(si.StartupInfo);
   
   /* Decide whether a child window should be shown.  */
-  si.dwFlags |= STARTF_USESHOWWINDOW;
-  si.wShowWindow = (unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT);
+  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.dwFlags = STARTF_USESTDHANDLES;
-  
-  /* Create the stderr pipe to be shared by all processes.  Neither
-     end is directly inherited.  */
-  if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
-                 &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
+  si.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
+
+  /* Create pipes to be shared by all processes in the pipeline.  */
+  for(i=KWSYSPE_PIPE_STDERR; i < KWSYSPE_PIPE_COUNT; ++i)
     {
-    kwsysProcessCleanup(cp, 1);
-    return;
-    }
+    /* Create a pipe.  Neither end is directly inherited.  */
+    if(!CreatePipe(&cp->Pipe[i].Read,
+                   &cp->Pipe[i].Write, 0, 0))
+      {
+      kwsysProcessCleanup(cp, 1);
+      for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+        {
+        kwsysProcessCleanupHandle(&si.InheritedWrite[i]);
+        }
+      return;
+      }
     
-  /* Create an inherited duplicate of the write end.  This also closes
-     the non-inherited version. */
-  if(!DuplicateHandle(GetCurrentProcess(), cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
-                      GetCurrentProcess(), &cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
-                      0, TRUE, (DUPLICATE_CLOSE_SOURCE |
-                                DUPLICATE_SAME_ACCESS)))
-    {
-    /* Write end is already closed.  */
-    cp->Pipe[KWSYSPE_PIPE_STDERR].Write = 0;
-    kwsysProcessCleanup(cp, 1);
-    return;
+    /* Create an inherited duplicate of the write end, but do not
+       close the non-inherited version.  We need to keep it open
+       to use in waking up the pipe threads.  */
+    if(!DuplicateHandle(GetCurrentProcess(), cp->Pipe[i].Write,
+                        GetCurrentProcess(), &si.InheritedWrite[i],
+                        0, TRUE, DUPLICATE_SAME_ACCESS))
+      {
+      /* Write end is already closed.  */
+      cp->Pipe[i].Write = 0;
+      kwsysProcessCleanup(cp, 1);
+      for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+        {
+        kwsysProcessCleanupHandle(&si.InheritedWrite[i]);
+        }
+      return;
+      }
     }
-  si.hStdError = cp->Pipe[KWSYSPE_PIPE_STDERR].Write;
+
+  /* All children will share the stderr pipe.  They will also share
+     the termination pipe, but will not be given handles to it.  This
+     will allow detection of process termination when the pipe closes.  */
+  si.StartupInfo.hStdError = si.InheritedWrite[KWSYSPE_PIPE_STDERR];
 
   /* Create the pipeline of processes.  */
   {
@@ -853,17 +883,28 @@ void kwsysProcess_Execute(kwsysProcess* cp)
       kwsysProcessCleanupHandle(&readEnd);
       if(i > 0)
         {
-        kwsysProcessCleanupHandle(&si.hStdInput);
+        kwsysProcessCleanupHandle(&si.StartupInfo.hStdInput);
+        }
+      kwsysProcessCleanupHandle(&si.StartupInfo.hStdOutput);
+      for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+        {
+        kwsysProcessCleanupHandle(&si.InheritedWrite[i]);
         }
-      kwsysProcessCleanupHandle(&si.hStdOutput);
       return;
       }
     }
-  /* Save handles to the output pipe for the last process.  */
-  cp->Pipe[KWSYSPE_PIPE_STDOUT].Write = si.hStdOutput;
+
+  /* Save a handle to the output pipe for the last process.  */
   cp->Pipe[KWSYSPE_PIPE_STDOUT].Read = readEnd;
   }
 
+  /* Close the inherited handles to the pipes shared by all processes
+     in the pipeline.  */
+  for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+    {
+    kwsysProcessCleanupHandle(&si.InheritedWrite[i]);
+    }
+
   /* The timeout period starts now.  */
   cp->StartTime = kwsysProcessTimeGetCurrent();
   cp->TimeoutTime = kwsysProcessTimeFromDouble(-1);
@@ -981,6 +1022,10 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data, int* leng
         /* The pipe closed.  */
         --cp->PipesLeft;
         }
+      else if(cp->CurrentIndex == KWSYSPE_PIPE_TERM)
+        {
+        /* This is data on the special termination pipe.  Ignore it.  */
+        }
       else if(pipes & (1 << cp->CurrentIndex))
         {
         /* Caller wants this data.  Report it.  */
@@ -1322,7 +1367,8 @@ int kwsysProcessInitialize(kwsysProcess* cp)
 }
 
 /*--------------------------------------------------------------------------*/
-int kwsysProcessCreate(kwsysProcess* cp, int index, STARTUPINFO* si,
+int kwsysProcessCreate(kwsysProcess* cp, int index,
+                       kwsysProcessCreateInformation* si,
                        PHANDLE readEnd)
 {
   HANDLE errorWriteEnd = 0;
@@ -1341,14 +1387,14 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, STARTUPINFO* si,
       {
       return 0;
       }
-    si->hStdInput = *readEnd;
+    si->StartupInfo.hStdInput = *readEnd;
 
     /* This function is done with this handle.  */
     *readEnd = 0;
     }
   else
     {
-    si->hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+    si->StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
     }
 
   /* Setup the process's stdout.  */
@@ -1362,16 +1408,31 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, STARTUPINFO* si,
     return 0;
     }
 
-  /* Create an inherited duplicate of the write end.  This also closes
-     the non-inherited version. */
-  if(!DuplicateHandle(GetCurrentProcess(), writeEnd,
-                      GetCurrentProcess(), &writeEnd,
-                      0, TRUE, (DUPLICATE_CLOSE_SOURCE |
-                                DUPLICATE_SAME_ACCESS)))
+  /* Create an inherited duplicate of the write end.  Close the
+     non-inherited version unless this is the last process.  Save the
+     non-inherited write end of the last process.  */
+  if(index == cp->NumberOfCommands-1)
     {
-    return 0;
+    cp->Pipe[KWSYSPE_PIPE_STDOUT].Write = writeEnd;
+    if(!DuplicateHandle(GetCurrentProcess(), writeEnd,
+                        GetCurrentProcess(), &writeEnd,
+                        0, TRUE, DUPLICATE_SAME_ACCESS))
+      {
+      return 0;
+      }
     }
-  si->hStdOutput = writeEnd;
+  else
+    {
+    if(!DuplicateHandle(GetCurrentProcess(), writeEnd,
+                        GetCurrentProcess(), &writeEnd,
+                        0, TRUE, (DUPLICATE_CLOSE_SOURCE |
+                                  DUPLICATE_SAME_ACCESS)))
+      {
+      return 0;
+      }
+    }
+
+  si->StartupInfo.hStdOutput = writeEnd;
   }
 
   /* Create the child process.  */
@@ -1399,7 +1460,7 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, STARTUPINFO* si,
       }
 
     /* The forwarding executable is given a handle to the error pipe
-       and a handle to the resume and kill events.  */
+       and resume and kill events.  */
     realCommand = malloc(strlen(cp->Win9x)+strlen(cp->Commands[index])+100);
     if(!realCommand)
       {
@@ -1420,7 +1481,8 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, STARTUPINFO* si,
      children have been created before running any one.  */
   r = CreateProcess(0, realCommand, 0, 0, TRUE,
                     cp->Win9x? 0 : CREATE_SUSPENDED, 0,
-                    cp->WorkingDirectory, si, &cp->ProcessInformation[index]);
+                    cp->WorkingDirectory, &si->StartupInfo,
+                    &cp->ProcessInformation[index]);
 
   if(cp->Win9x)
     {
@@ -1475,14 +1537,12 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, STARTUPINFO* si,
   if(index > 0)
     {
     /* Close our handle to the input pipe for the current process.  */
-    kwsysProcessCleanupHandle(&si->hStdInput);
-    }
-  if(index < cp->NumberOfCommands-1)
-    {
-    /* Close our handle to the output pipe for the current process.  */
-    kwsysProcessCleanupHandle(&si->hStdOutput);
+    kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput);
     }
 
+  /* The parent process does not need the inhertied pipe write end.  */
+  kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
+
   return 1;
 }