[Cmake-commits] CMake branch, next, updated. v3.2.2-2510-g801b520

Brad King brad.king at kitware.com
Tue May 5 09:20:45 EDT 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  801b5203b36a6bdfea0fefc1ee58b77337a79b21 (commit)
       via  a874700fc2da9331140e93df4088c6a1021d3cc3 (commit)
       via  71f38d060bb729e1ac6cfe8db412c0ef96b68cc7 (commit)
       via  f6749f727451ef3e35c20e80e712f0bda38348f9 (commit)
       via  0c34ac2f0159645f6a2cd0f57a45ffae36b4352d (commit)
      from  9fa1bcba9125efa0a379f16d1019c2dde1c2282f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=801b5203b36a6bdfea0fefc1ee58b77337a79b21
commit 801b5203b36a6bdfea0fefc1ee58b77337a79b21
Merge: 9fa1bcb a874700
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue May 5 09:20:44 2015 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue May 5 09:20:44 2015 -0400

    Merge topic 'update-kwsys' into next
    
    a874700f Merge branch 'upstream-kwsys' into update-kwsys
    71f38d06 KWSys 2015-05-05 (8c8b2273)
    f6749f72 Merge branch 'upstream-kwsys' into update-kwsys
    0c34ac2f KWSys 2015-05-04 (c2387a4b)


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a874700fc2da9331140e93df4088c6a1021d3cc3
commit a874700fc2da9331140e93df4088c6a1021d3cc3
Merge: f6749f7 71f38d0
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue May 5 09:13:24 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 5 09:13:24 2015 -0400

    Merge branch 'upstream-kwsys' into update-kwsys


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=71f38d060bb729e1ac6cfe8db412c0ef96b68cc7
commit 71f38d060bb729e1ac6cfe8db412c0ef96b68cc7
Author:     KWSys Robot <kwrobot at kitware.com>
AuthorDate: Tue May 5 09:05:29 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 5 09:13:21 2015 -0400

    KWSys 2015-05-05 (8c8b2273)
    
    Extract upstream KWSys using the following shell commands.
    
    $ git archive --prefix=upstream-kwsys/ 8c8b2273 | tar x
    $ git shortlog --no-merges --abbrev=8 --format='%h %s' c2387a4b..8c8b2273
    Brad King (1):
          8c8b2273 Process: Refactor child pipe creation

diff --git a/ProcessUNIX.c b/ProcessUNIX.c
index 1be6d02..68722c2 100644
--- a/ProcessUNIX.c
+++ b/ProcessUNIX.c
@@ -157,7 +157,7 @@ static void kwsysProcessCleanupDescriptor(int* pfd);
 static void kwsysProcessClosePipes(kwsysProcess* cp);
 static int kwsysProcessSetNonBlocking(int fd);
 static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
-                              kwsysProcessCreateInformation* si, int* readEnd);
+                              kwsysProcessCreateInformation* si);
 static void kwsysProcessDestroy(kwsysProcess* cp);
 static int kwsysProcessSetupOutputPipeFile(int* p, const char* name);
 static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]);
@@ -203,6 +203,10 @@ struct kwsysProcess_s
      the signal pipe. */
   int PipeReadEnds[KWSYSPE_PIPE_COUNT];
 
+  /* Descriptors for the child's ends of the pipes.
+     Used temporarily during process creation.  */
+  int PipeChildStd[3];
+
   /* Write descriptor for child termination signal pipe.  */
   int SignalPipe;
 
@@ -717,7 +721,6 @@ const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
 void kwsysProcess_Execute(kwsysProcess* cp)
 {
   int i;
-  kwsysProcessCreateInformation si = {-1, -1, -1, {-1, -1}};
 
   /* Do not execute a second copy simultaneously.  */
   if(!cp || cp->State == kwsysProcess_State_Executing)
@@ -785,7 +788,50 @@ void kwsysProcess_Execute(kwsysProcess* cp)
       }
     }
 
-  /* Setup the stderr pipe to be shared by all processes.  */
+  /* Setup the stdin pipe for the first process.  */
+  if(cp->PipeFileSTDIN)
+    {
+    /* Open a file for the child's stdin to read.  */
+    cp->PipeChildStd[0] = open(cp->PipeFileSTDIN, O_RDONLY);
+    if(cp->PipeChildStd[0] < 0)
+      {
+      kwsysProcessCleanup(cp, 1);
+      return;
+      }
+
+    /* Set close-on-exec flag on the pipe's end.  */
+    if(fcntl(cp->PipeChildStd[0], F_SETFD, FD_CLOEXEC) < 0)
+      {
+      kwsysProcessCleanup(cp, 1);
+      return;
+      }
+    }
+  else if(cp->PipeSharedSTDIN)
+    {
+    cp->PipeChildStd[0] = 0;
+    }
+  else if(cp->PipeNativeSTDIN[0] >= 0)
+    {
+    cp->PipeChildStd[0] = cp->PipeNativeSTDIN[0];
+
+    /* Set close-on-exec flag on the pipe's ends.  The read end will
+       be dup2-ed into the stdin descriptor after the fork but before
+       the exec.  */
+    if((fcntl(cp->PipeNativeSTDIN[0], F_SETFD, FD_CLOEXEC) < 0) ||
+       (fcntl(cp->PipeNativeSTDIN[1], F_SETFD, FD_CLOEXEC) < 0))
+      {
+      kwsysProcessCleanup(cp, 1);
+      return;
+      }
+    }
+  else
+    {
+    cp->PipeChildStd[0] = -1;
+    }
+
+  /* Create the output pipe for the last process.
+     We always create this so the pipe can be passed to select even if
+     it will report closed immediately.  */
   {
   /* Create the pipe.  */
   int p[2];
@@ -796,15 +842,14 @@ void kwsysProcess_Execute(kwsysProcess* cp)
     }
 
   /* Store the pipe.  */
-  cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0];
-  si.StdErr = p[1];
+  cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = p[0];
+  cp->PipeChildStd[1] = 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);
     return;
     }
 
@@ -813,41 +858,93 @@ void kwsysProcess_Execute(kwsysProcess* cp)
   if(!kwsysProcessSetNonBlocking(p[0]))
     {
     kwsysProcessCleanup(cp, 1);
-    kwsysProcessCleanupDescriptor(&si.StdErr);
     return;
     }
   }
 
-  /* Replace the stderr pipe with a file if requested.  In this case
-     the select call will report that stderr is closed immediately.  */
-  if(cp->PipeFileSTDERR)
+  if (cp->PipeFileSTDOUT)
     {
-    if(!kwsysProcessSetupOutputPipeFile(&si.StdErr, cp->PipeFileSTDERR))
+    /* Use a file for stdout.  */
+    if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
+                                        cp->PipeFileSTDOUT))
       {
       kwsysProcessCleanup(cp, 1);
-      kwsysProcessCleanupDescriptor(&si.StdErr);
       return;
       }
     }
+  else if (cp->PipeSharedSTDOUT)
+    {
+    /* Use the parent stdout.  */
+    kwsysProcessCleanupDescriptor(&cp->PipeChildStd[1]);
+    cp->PipeChildStd[1] = 1;
+    }
+  else if (cp->PipeNativeSTDOUT[1] >= 0)
+    {
+    /* Use the given descriptor for stdout.  */
+    if(!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[1],
+                                          cp->PipeNativeSTDOUT))
+      {
+      kwsysProcessCleanup(cp, 1);
+      return;
+      }
+    }
+
+  /* Create stderr pipe to be shared by all processes in the pipeline.
+     We always create this so the pipe can be passed to select even if
+     it will report closed immediately.  */
+  {
+  /* Create the pipe.  */
+  int p[2];
+  if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
+    {
+    kwsysProcessCleanup(cp, 1);
+    return;
+    }
+
+  /* Store the pipe.  */
+  cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0];
+  cp->PipeChildStd[2] = p[1];
 
-  /* Replace the stderr pipe with the parent's if requested.  In this
-     case the select call will report that stderr is closed
-     immediately.  */
-  if(cp->PipeSharedSTDERR)
+  /* 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))
     {
-    kwsysProcessCleanupDescriptor(&si.StdErr);
-    si.StdErr = 2;
+    kwsysProcessCleanup(cp, 1);
+    return;
     }
 
-  /* Replace the stderr pipe with the native pipe provided if any.  In
-     this case the select call will report that stderr is closed
-     immediately.  */
-  if(cp->PipeNativeSTDERR[1] >= 0)
+  /* Set to non-blocking in case select lies, or for the polling
+     implementation.  */
+  if(!kwsysProcessSetNonBlocking(p[0]))
     {
-    if(!kwsysProcessSetupOutputPipeNative(&si.StdErr, cp->PipeNativeSTDERR))
+    kwsysProcessCleanup(cp, 1);
+    return;
+    }
+  }
+
+  if (cp->PipeFileSTDERR)
+    {
+    /* Use a file for stderr.  */
+    if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
+                                        cp->PipeFileSTDERR))
+      {
+      kwsysProcessCleanup(cp, 1);
+      return;
+      }
+    }
+  else if (cp->PipeSharedSTDERR)
+    {
+    /* Use the parent stderr.  */
+    kwsysProcessCleanupDescriptor(&cp->PipeChildStd[2]);
+    cp->PipeChildStd[2] = 2;
+    }
+  else if (cp->PipeNativeSTDERR[1] >= 0)
+    {
+    /* Use the given handle for stderr.  */
+    if(!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[2],
+                                          cp->PipeNativeSTDERR))
       {
       kwsysProcessCleanup(cp, 1);
-      kwsysProcessCleanupDescriptor(&si.StdErr);
       return;
       }
     }
@@ -859,54 +956,85 @@ void kwsysProcess_Execute(kwsysProcess* cp)
 
   /* Create the pipeline of processes.  */
   {
-  int readEnd = -1;
-  int failed = 0;
+  kwsysProcessCreateInformation si = {-1, -1, -1, {-1, -1}};
+  int nextStdIn = cp->PipeChildStd[0];
   for(i=0; i < cp->NumberOfCommands; ++i)
     {
-    if(!kwsysProcessCreate(cp, i, &si, &readEnd))
+    /* Setup the process's pipes.  */
+    si.StdIn = nextStdIn;
+    if (i == cp->NumberOfCommands-1)
       {
-      failed = 1;
+      nextStdIn = -1;
+      si.StdOut = cp->PipeChildStd[1];
       }
-
-    /* Set the output pipe of the last process to be non-blocking in
-       case select lies, or for the polling implementation.  */
-    if(i == (cp->NumberOfCommands-1) && !kwsysProcessSetNonBlocking(readEnd))
-      {
-      failed = 1;
-      }
-
-    if(failed)
+    else
       {
-      kwsysProcessCleanup(cp, 1);
-
-      /* Release resources that may have been allocated for this
-         process before an error occurred.  */
-      kwsysProcessCleanupDescriptor(&readEnd);
-      if(si.StdIn != 0)
+      /* Create a pipe to sit between the children.  */
+      int p[2] = {-1,-1};
+      if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
         {
-        kwsysProcessCleanupDescriptor(&si.StdIn);
-        }
-      if(si.StdOut != 1)
-        {
-        kwsysProcessCleanupDescriptor(&si.StdOut);
+        if (nextStdIn != cp->PipeChildStd[0])
+          {
+          kwsysProcessCleanupDescriptor(&nextStdIn);
+          }
+        kwsysProcessCleanup(cp, 1);
+        return;
         }
-      if(si.StdErr != 2)
+
+      /* 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))
         {
-        kwsysProcessCleanupDescriptor(&si.StdErr);
+        close(p[0]);
+        close(p[1]);
+        if (nextStdIn != cp->PipeChildStd[0])
+          {
+          kwsysProcessCleanupDescriptor(&nextStdIn);
+          }
+        kwsysProcessCleanup(cp, 1);
+        return;
         }
+      nextStdIn = p[0];
+      si.StdOut = p[1];
+      }
+    si.StdErr = cp->PipeChildStd[2];
+
+    {
+    int res = kwsysProcessCreate(cp, i, &si);
+
+    /* Close our copies of pipes used between children.  */
+    if (si.StdIn != cp->PipeChildStd[0])
+      {
+      kwsysProcessCleanupDescriptor(&si.StdIn);
+      }
+    if (si.StdOut != cp->PipeChildStd[1])
+      {
+      kwsysProcessCleanupDescriptor(&si.StdOut);
+      }
+    if (si.StdErr != cp->PipeChildStd[2])
+      {
+      kwsysProcessCleanupDescriptor(&si.StdErr);
+      }
+
+    if(!res)
+      {
       kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]);
       kwsysProcessCleanupDescriptor(&si.ErrorPipe[1]);
+      if (nextStdIn != cp->PipeChildStd[0])
+        {
+        kwsysProcessCleanupDescriptor(&nextStdIn);
+        }
+      kwsysProcessCleanup(cp, 1);
       return;
       }
     }
-  /* Save a handle to the output pipe for the last process.  */
-  cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = readEnd;
+    }
   }
 
-  /* The parent process does not need the output pipe write ends.  */
-  if(si.StdErr != 2)
+  /* The parent process does not need the child's pipe ends.  */
+  for (i=0; i < 3; ++i)
     {
-    kwsysProcessCleanupDescriptor(&si.StdErr);
+    kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]);
     }
 
   /* Restore the working directory. */
@@ -1414,6 +1542,10 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
     {
     cp->PipeReadEnds[i] = -1;
     }
+  for(i=0; i < 3; ++i)
+    {
+    cp->PipeChildStd[i] = -1;
+    }
   cp->SignalPipe = -1;
   cp->SelectError = 0;
   cp->StartTime.tv_sec = -1;
@@ -1548,13 +1680,17 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error)
     {
     kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
     }
+  for(i=0; i < 3; ++i)
+    {
+    kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]);
+    }
 }
 
 /*--------------------------------------------------------------------------*/
 /* Close the given file descriptor if it is open.  Reset its value to -1.  */
 static void kwsysProcessCleanupDescriptor(int* pfd)
 {
-  if(pfd && *pfd >= 0)
+  if(pfd && *pfd > 2)
     {
     /* Keep trying to close until it is not interrupted by a
      * signal.  */
@@ -1615,100 +1751,8 @@ int decc$set_child_standard_streams(int fd1, int fd2, int fd3);
 
 /*--------------------------------------------------------------------------*/
 static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
-                              kwsysProcessCreateInformation* si, int* readEnd)
+                              kwsysProcessCreateInformation* si)
 {
-  /* Setup the process's stdin.  */
-  if(prIndex > 0)
-    {
-    si->StdIn = *readEnd;
-    *readEnd = 0;
-    }
-  else if(cp->PipeFileSTDIN)
-    {
-    /* Open a file for the child's stdin to read.  */
-    si->StdIn = open(cp->PipeFileSTDIN, O_RDONLY);
-    if(si->StdIn < 0)
-      {
-      return 0;
-      }
-
-    /* Set close-on-exec flag on the pipe's end.  */
-    if(fcntl(si->StdIn, F_SETFD, FD_CLOEXEC) < 0)
-      {
-      return 0;
-      }
-    }
-  else if(cp->PipeSharedSTDIN)
-    {
-    si->StdIn = 0;
-    }
-  else if(cp->PipeNativeSTDIN[0] >= 0)
-    {
-    si->StdIn = cp->PipeNativeSTDIN[0];
-
-    /* Set close-on-exec flag on the pipe's ends.  The read end will
-       be dup2-ed into the stdin descriptor after the fork but before
-       the exec.  */
-    if((fcntl(cp->PipeNativeSTDIN[0], F_SETFD, FD_CLOEXEC) < 0) ||
-       (fcntl(cp->PipeNativeSTDIN[1], F_SETFD, FD_CLOEXEC) < 0))
-      {
-      return 0;
-      }
-    }
-  else
-    {
-    si->StdIn = -1;
-    }
-
-  /* Setup the process's stdout.  */
-  {
-  /* Create the pipe.  */
-  int p[2];
-  if(pipe(p KWSYSPE_VMS_NONBLOCK) < 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;
-    }
-  }
-
-  /* Replace the stdout pipe with a file if requested.  In this case
-     the select call will report that stdout is closed immediately.  */
-  if(prIndex == cp->NumberOfCommands-1 && cp->PipeFileSTDOUT)
-    {
-    if(!kwsysProcessSetupOutputPipeFile(&si->StdOut, cp->PipeFileSTDOUT))
-      {
-      return 0;
-      }
-    }
-
-  /* Replace the stdout pipe with the parent's if requested.  In this
-     case the select call will report that stderr is closed
-     immediately.  */
-  if(prIndex == cp->NumberOfCommands-1 && cp->PipeSharedSTDOUT)
-    {
-    kwsysProcessCleanupDescriptor(&si->StdOut);
-    si->StdOut = 1;
-    }
-
-  /* Replace the stdout pipe with the native pipe provided if any.  In
-     this case the select call will report that stdout is closed
-     immediately.  */
-  if(prIndex == cp->NumberOfCommands-1 && cp->PipeNativeSTDOUT[1] >= 0)
-    {
-    if(!kwsysProcessSetupOutputPipeNative(&si->StdOut, cp->PipeNativeSTDOUT))
-      {
-      return 0;
-      }
-    }
-
   /* Create the error reporting pipe.  */
   if(pipe(si->ErrorPipe) < 0)
     {
@@ -1819,19 +1863,6 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
     }
   }
 
-  /* Successfully created this child process.  */
-  if(prIndex > 0 || si->StdIn > 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.  */
-  if(si->StdOut != 1)
-    {
-    kwsysProcessCleanupDescriptor(&si->StdOut);
-    }
-
   return 1;
 }
 
diff --git a/ProcessWin32.c b/ProcessWin32.c
index c2965ea..da1bc15 100644
--- a/ProcessWin32.c
+++ b/ProcessWin32.c
@@ -94,6 +94,11 @@ typedef struct kwsysProcessCreateInformation_s
 {
   /* Windows child startup control data.  */
   STARTUPINFOW StartupInfo;
+
+  /* Original handles before making inherited duplicates.  */
+  HANDLE hStdInput;
+  HANDLE hStdOutput;
+  HANDLE hStdError;
 } kwsysProcessCreateInformation;
 
 
@@ -107,15 +112,12 @@ static void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp,
                                            kwsysProcessPipeData* td);
 static int kwsysProcessInitialize(kwsysProcess* cp);
 static int kwsysProcessCreate(kwsysProcess* cp, int index,
-                              kwsysProcessCreateInformation* si,
-                              PHANDLE readEnd);
+                              kwsysProcessCreateInformation* si);
 static void kwsysProcessDestroy(kwsysProcess* cp, int event);
 static int kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name);
-static int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
-static int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2],
-                                       int isWrite);
+static void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
+static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle);
 static void kwsysProcessCleanupHandle(PHANDLE h);
-static void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle);
 static void kwsysProcessCleanup(kwsysProcess* cp, int error);
 static void kwsysProcessCleanErrorMessage(kwsysProcess* cp);
 static int kwsysProcessComputeCommandLength(kwsysProcess* cp,
@@ -306,6 +308,10 @@ struct kwsysProcess_s
   /* 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];
 };
 
 /*--------------------------------------------------------------------------*/
@@ -446,6 +452,10 @@ kwsysProcess* kwsysProcess_New(void)
       return 0;
       }
     }
+  for(i=0; i < 3; ++i)
+    {
+    cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
+    }
 
   return cp;
 }
@@ -875,9 +885,6 @@ void kwsysProcess_Execute(kwsysProcess* cp)
 {
   int i;
 
-  /* Child startup control data.  */
-  kwsysProcessCreateInformation si;
-
   /* Do not execute a second time.  */
   if(!cp || cp->State == kwsysProcess_State_Executing)
     {
@@ -914,117 +921,211 @@ void kwsysProcess_Execute(kwsysProcess* cp)
     SetCurrentDirectoryW(cp->WorkingDirectory);
     }
 
-  /* 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;
 
-  /* Create stderr pipe to be shared by all processes in the pipeline.
-     Neither end is directly inherited.  */
-  if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
-                 &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
+  /* Setup the stdin pipe for the first process.  */
+  if(cp->PipeFileSTDIN)
     {
-    kwsysProcessCleanup(cp, 1);
-    return;
+    /* Create a handle to read a file for stdin.  */
+    wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN);
+    cp->PipeChildStd[0] =
+      CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE,
+                  FILE_SHARE_READ|FILE_SHARE_WRITE,
+                  0, OPEN_EXISTING, 0, 0);
+    free(wstdin);
+    if(cp->PipeChildStd[0] == INVALID_HANDLE_VALUE)
+      {
+      kwsysProcessCleanup(cp, 1);
+      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 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[KWSYSPE_PIPE_STDERR].Write,
-                      GetCurrentProcess(), &si.StartupInfo.hStdError,
-                      0, TRUE, DUPLICATE_SAME_ACCESS))
+  /* 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, 1);
-    kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
     return;
     }
 
-  /* Replace the stderr pipe with a file if requested.  In this case
-     the pipe thread will still run but never report data.  */
-  if(cp->PipeFileSTDERR)
+  if(cp->PipeFileSTDOUT)
     {
-    if(!kwsysProcessSetupOutputPipeFile(&si.StartupInfo.hStdError,
-                                        cp->PipeFileSTDERR))
+    /* Use a file for stdout.  */
+    if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
+                                        cp->PipeFileSTDOUT))
       {
       kwsysProcessCleanup(cp, 1);
-      kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
       return;
       }
     }
-
-  /* Replace the stderr pipe with the parent process's if requested.
-     In this case the pipe thread will still run but never report
-     data.  */
-  if(cp->PipeSharedSTDERR)
+  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
     {
-    if(!kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE,
-                                    &si.StartupInfo.hStdError))
+    /* 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, 1);
-      kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
-                                    STD_ERROR_HANDLE);
       return;
       }
     }
 
-  /* Replace the stderr pipe with the native pipe provided if any.  In
-     this case the pipe thread will still run but never report
-     data.  */
-  if(cp->PipeNativeSTDERR[1])
+  /* 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, 1);
+    return;
+    }
+
+  if(cp->PipeFileSTDERR)
+    {
+    /* Use a file for stderr.  */
+    if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
+                                        cp->PipeFileSTDERR))
+      {
+      kwsysProcessCleanup(cp, 1);
+      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
     {
-    if(!kwsysProcessSetupPipeNative(&si.StartupInfo.hStdError,
-                                    cp->PipeNativeSTDERR, 1))
+    /* 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, 1);
-      kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
-                                    STD_ERROR_HANDLE);
       return;
       }
     }
 
   /* Create the pipeline of processes.  */
   {
-  HANDLE readEnd = 0;
+  /* 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)
     {
-    if(kwsysProcessCreate(cp, i, &si, &readEnd))
+    /* 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))
+        {
+        if (nextStdInput != cp->PipeChildStd[0])
+          {
+          kwsysProcessCleanupHandle(&nextStdInput);
+          }
+        kwsysProcessCleanup(cp, 1);
+        return;
+        }
+      nextStdInput = p[0];
+      si.hStdOutput = p[1];
+      }
+    si.hStdError = cp->PipeChildStd[2];
+
+    {
+    int res = 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])
+      {
+      kwsysProcessCleanupHandle(&si.hStdError);
+      }
+    if (res)
       {
       cp->ProcessEvents[i+1] = cp->ProcessInformation[i].hProcess;
       }
     else
       {
+      if (nextStdInput != cp->PipeChildStd[0])
+        {
+        kwsysProcessCleanupHandle(&nextStdInput);
+        }
       kwsysProcessCleanup(cp, 1);
-
-      /* Release resources that may have been allocated for this
-         process before an error occurred.  */
-      kwsysProcessCleanupHandle(&readEnd);
-      kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdInput,
-                                    STD_INPUT_HANDLE);
-      kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdOutput,
-                                    STD_OUTPUT_HANDLE);
-      kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
-                                    STD_ERROR_HANDLE);
       return;
       }
     }
-
-  /* Save a handle to the output pipe for the last process.  */
-  cp->Pipe[KWSYSPE_PIPE_STDOUT].Read = readEnd;
+    }
   }
 
-  /* Close the inherited handles to the stderr pipe shared by all
-     processes in the pipeline.  The stdout and stdin pipes are not
-     shared among all children and are therefore closed by
-     kwsysProcessCreate after each child is created.  */
-  kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, STD_ERROR_HANDLE);
+  /* 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)
@@ -1543,162 +1644,90 @@ int kwsysProcessInitialize(kwsysProcess* cp)
         }
       }
     }
+  {
+  int i;
+  for (i=0; i < 3; ++i)
+    {
+    cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
+    }
+  }
 
   return 1;
 }
 
 /*--------------------------------------------------------------------------*/
-int kwsysProcessCreate(kwsysProcess* cp, int index,
-                       kwsysProcessCreateInformation* si,
-                       PHANDLE readEnd)
+static int kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
 {
-  /* Setup the process's stdin.  */
-  if(*readEnd)
-    {
-    /* Create an inherited duplicate of the read end from the output
-       pipe of the previous process.  This also closes the
-       non-inherited version. */
-    if(!DuplicateHandle(GetCurrentProcess(), *readEnd,
-                        GetCurrentProcess(), readEnd,
-                        0, TRUE, (DUPLICATE_CLOSE_SOURCE |
-                                  DUPLICATE_SAME_ACCESS)))
-      {
-      return 0;
-      }
-    si->StartupInfo.hStdInput = *readEnd;
+  DWORD flags;
 
-    /* This function is done with this handle.  */
-    *readEnd = 0;
-    }
-  else if(cp->PipeFileSTDIN)
-    {
-    /* Create a handle to read a file for stdin.  */
-    wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN);
-    HANDLE fin = CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE,
-                            FILE_SHARE_READ|FILE_SHARE_WRITE,
-                            0, OPEN_EXISTING, 0, 0);
-    free(wstdin);
-    if(fin == INVALID_HANDLE_VALUE)
-      {
-      return 0;
-      }
-    /* Create an inherited duplicate of the handle.  This also closes
-       the non-inherited version.  */
-    if(!DuplicateHandle(GetCurrentProcess(), fin,
-                        GetCurrentProcess(), &fin,
-                        0, TRUE, (DUPLICATE_CLOSE_SOURCE |
-                                  DUPLICATE_SAME_ACCESS)))
-      {
-      return 0;
-      }
-    si->StartupInfo.hStdInput = fin;
-    }
-  else if(cp->PipeSharedSTDIN)
-    {
-    /* Share this process's stdin with the child.  */
-    if(!kwsysProcessSetupSharedPipe(STD_INPUT_HANDLE,
-                                    &si->StartupInfo.hStdInput))
-      {
-      return 0;
-      }
-    }
-  else if(cp->PipeNativeSTDIN[0])
+  /* Check whether the handle is valid for this process.  */
+  if (in != INVALID_HANDLE_VALUE && GetHandleInformation(in, &flags))
     {
-    /* Use the provided native pipe.  */
-    if(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdInput,
-                                    cp->PipeNativeSTDIN, 0))
+    /* Use the handle as-is if it is already inherited.  */
+    if (flags & HANDLE_FLAG_INHERIT)
       {
-      return 0;
+      *out = in;
+      return 1;
       }
+
+    /* Create an inherited copy of this handle.  */
+    return DuplicateHandle(GetCurrentProcess(), in,
+                           GetCurrentProcess(), out,
+                           0, TRUE, DUPLICATE_SAME_ACCESS);
     }
   else
     {
-    /* Explicitly give the child no stdin.  */
-    si->StartupInfo.hStdInput = INVALID_HANDLE_VALUE;
+    /* 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;
     }
 
-  /* Setup the process's stdout.  */
-  {
-  DWORD maybeClose = DUPLICATE_CLOSE_SOURCE;
-  HANDLE writeEnd;
+}
 
-  /* Create the output pipe for this process.  Neither end is directly
-     inherited.  */
-  if(!CreatePipe(readEnd, &writeEnd, 0, 0))
-    {
-    return 0;
-    }
+/*--------------------------------------------------------------------------*/
+int kwsysProcessCreate(kwsysProcess* cp, int index,
+                       kwsysProcessCreateInformation* si)
+{
+  int res =
 
-  /* 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)
-    {
-    cp->Pipe[KWSYSPE_PIPE_STDOUT].Write = writeEnd;
-    maybeClose = 0;
-    }
-  if(!DuplicateHandle(GetCurrentProcess(), writeEnd,
-                      GetCurrentProcess(), &writeEnd,
-                      0, TRUE, (maybeClose | DUPLICATE_SAME_ACCESS)))
-    {
-    return 0;
-    }
-  si->StartupInfo.hStdOutput = writeEnd;
-  }
+    /* Create inherited copies the handles.  */
+    kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput,
+                                  si->hStdInput, 1) &&
+    kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
+                                  si->hStdOutput, 0) &&
+    kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
+                                  si->hStdError, 0) &&
 
-  /* Replace the stdout pipe with a file if requested.  In this case
-     the pipe thread will still run but never report data.  */
-  if(index == cp->NumberOfCommands-1 && cp->PipeFileSTDOUT)
-    {
-    if(!kwsysProcessSetupOutputPipeFile(&si->StartupInfo.hStdOutput,
-                                        cp->PipeFileSTDOUT))
-      {
-      return 0;
-      }
-    }
+    /* Create the child in a suspended state so we can wait until all
+       children have been created before running any one.  */
+    CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0,
+                   0, &si->StartupInfo, &cp->ProcessInformation[index]);
 
-  /* Replace the stdout pipe of the last child with the parent
-     process's if requested.  In this case the pipe thread will still
-     run but never report data.  */
-  if(index == cp->NumberOfCommands-1 && cp->PipeSharedSTDOUT)
+  /* Close the inherited copies of the handles. */
+  if (si->StartupInfo.hStdInput != si->hStdInput)
     {
-    if(!kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE,
-                                    &si->StartupInfo.hStdOutput))
-      {
-      return 0;
-      }
+    kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput);
     }
-
-  /* Replace the stdout pipe with the native pipe provided if any.  In
-     this case the pipe thread will still run but never report
-     data.  */
-  if(index == cp->NumberOfCommands-1 && cp->PipeNativeSTDOUT[1])
+  if (si->StartupInfo.hStdOutput != si->hStdOutput)
     {
-    if(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdOutput,
-                                    cp->PipeNativeSTDOUT, 1))
-      {
-      return 0;
-      }
+    kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
     }
-
-  /* Create the child in a suspended state so we can wait until all
-     children have been created before running any one.  */
-  if(!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0,
-                    0, &si->StartupInfo, &cp->ProcessInformation[index]))
+  if (si->StartupInfo.hStdError != si->hStdError)
     {
-    return 0;
+    kwsysProcessCleanupHandle(&si->StartupInfo.hStdError);
     }
 
-  /* Successfully created this child process.  Close the current
-     process's copies of the inherited stdout and stdin handles.  The
-     stderr handle is shared among all children and is closed by
-     kwsysProcess_Execute after all children have been created.  */
-  kwsysProcessCleanupHandleSafe(&si->StartupInfo.hStdInput,
-                                STD_INPUT_HANDLE);
-  kwsysProcessCleanupHandleSafe(&si->StartupInfo.hStdOutput,
-                                STD_OUTPUT_HANDLE);
-
-  return 1;
+  return res;
 }
 
 /*--------------------------------------------------------------------------*/
@@ -1763,7 +1792,7 @@ int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
     return 1;
     }
 
-  /* Close the existing inherited handle.  */
+  /* Close the existing handle.  */
   kwsysProcessCleanupHandle(phandle);
 
   /* Create a handle to write a file for the pipe.  */
@@ -1776,103 +1805,27 @@ int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
     return 0;
     }
 
-  /* Create an inherited duplicate of the handle.  This also closes
-     the non-inherited version.  */
-  if(!DuplicateHandle(GetCurrentProcess(), fout,
-                      GetCurrentProcess(), &fout,
-                      0, TRUE, (DUPLICATE_CLOSE_SOURCE |
-                                DUPLICATE_SAME_ACCESS)))
-    {
-    return 0;
-    }
-
   /* Assign the replacement handle.  */
   *phandle = fout;
   return 1;
 }
 
 /*--------------------------------------------------------------------------*/
-int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle)
+void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle)
 {
-  /* Check whether the handle to be shared is already inherited.  */
-  DWORD flags;
-  int inherited = 0;
-  if(GetHandleInformation(GetStdHandle(nStdHandle), &flags) &&
-     (flags & HANDLE_FLAG_INHERIT))
-    {
-    inherited = 1;
-    }
-
-  /* Cleanup the previous handle.  */
+  /* Close the existing handle.  */
   kwsysProcessCleanupHandle(handle);
-
-  /* If the standard handle is not inherited then duplicate it to
-     create an inherited copy.  Do not close the original handle when
-     duplicating!  */
-  if(inherited)
-    {
-    *handle = GetStdHandle(nStdHandle);
-    return 1;
-    }
-  else if(DuplicateHandle(GetCurrentProcess(), GetStdHandle(nStdHandle),
-                          GetCurrentProcess(), handle,
-                          0, TRUE, DUPLICATE_SAME_ACCESS))
-    {
-    return 1;
-    }
-  else
-    {
-    /* The given standard handle is not valid for this process.  Some
-       child processes may break if they do not have a valid standard
-       pipe, so give the child an empty pipe.  For the stdin pipe we
-       want to close the write end and give the read end to the child.
-       For stdout and stderr we want to close the read end and give
-       the write end to the child.  */
-    int child_end = (nStdHandle == STD_INPUT_HANDLE)? 0:1;
-    int parent_end = (nStdHandle == STD_INPUT_HANDLE)? 1:0;
-    HANDLE emptyPipe[2];
-    if(!CreatePipe(&emptyPipe[0], &emptyPipe[1], 0, 0))
-      {
-      return 0;
-      }
-
-    /* Close the non-inherited end so the pipe will be broken
-       immediately.  */
-    CloseHandle(emptyPipe[parent_end]);
-
-    /* Create an inherited duplicate of the handle.  This also
-       closes the non-inherited version.  */
-    if(!DuplicateHandle(GetCurrentProcess(), emptyPipe[child_end],
-                        GetCurrentProcess(), &emptyPipe[child_end],
-                        0, TRUE, (DUPLICATE_CLOSE_SOURCE |
-                                  DUPLICATE_SAME_ACCESS)))
-      {
-      return 0;
-      }
-
-    /* Give the inherited handle to the child.  */
-    *handle = emptyPipe[child_end];
-    return 1;
-    }
+  /* Store the new standard handle.  */
+  *handle = GetStdHandle(nStdHandle);
 }
 
 /*--------------------------------------------------------------------------*/
-int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2], int isWrite)
+void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle)
 {
-  /* Close the existing inherited handle.  */
+  /* Close the existing handle.  */
   kwsysProcessCleanupHandle(handle);
-
-  /* Create an inherited duplicate of the handle.  This also closes
-     the non-inherited version.  */
-  if(!DuplicateHandle(GetCurrentProcess(), p[isWrite? 1:0],
-                      GetCurrentProcess(), handle,
-                      0, TRUE, (DUPLICATE_CLOSE_SOURCE |
-                                DUPLICATE_SAME_ACCESS)))
-    {
-    return 0;
-    }
-
-  return 1;
+  /* Store the new given handle.  */
+  *handle = native;
 }
 
 /*--------------------------------------------------------------------------*/
@@ -1880,23 +1833,13 @@ int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2], int isWrite)
 /* Close the given handle if it is open.  Reset its value to 0.  */
 void kwsysProcessCleanupHandle(PHANDLE h)
 {
-  if(h && *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 = 0;
-    }
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* Close the given handle if it is open and not a standard handle.
-   Reset its value to 0.  */
-void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle)
-{
-  if(h && *h && (*h != GetStdHandle(nStdHandle)))
-    {
-    CloseHandle(*h);
-    *h = 0;
+    *h = INVALID_HANDLE_VALUE;
     }
 }
 
@@ -1986,6 +1929,10 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
     kwsysProcessCleanupHandle(&cp->Pipe[i].Read);
     cp->Pipe[i].Closed = 0;
     }
+  for(i=0; i < 3; ++i)
+    {
+    kwsysProcessCleanupHandle(&cp->PipeChildStd[i]);
+    }
 }
 
 /*--------------------------------------------------------------------------*/

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f6749f727451ef3e35c20e80e712f0bda38348f9
commit f6749f727451ef3e35c20e80e712f0bda38348f9
Merge: 9e3181a 0c34ac2
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue May 5 09:12:21 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 5 09:12:21 2015 -0400

    Merge branch 'upstream-kwsys' into update-kwsys

diff --cc Source/kwsys/.gitattributes
index 0000000,248786e..248786e
mode 000000,100644..100644
--- a/Source/kwsys/.gitattributes
+++ b/Source/kwsys/.gitattributes

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0c34ac2f0159645f6a2cd0f57a45ffae36b4352d
commit 0c34ac2f0159645f6a2cd0f57a45ffae36b4352d
Author:     KWSys Robot <kwrobot at kitware.com>
AuthorDate: Mon May 4 10:27:45 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 5 09:12:18 2015 -0400

    KWSys 2015-05-04 (c2387a4b)
    
    Extract upstream KWSys using the following shell commands.
    
    $ git archive --prefix=upstream-kwsys/ c2387a4b | tar x
    $ git shortlog --no-merges --abbrev=8 --format='%h %s' 69bccf2e..c2387a4b
    Brad King (3):
          1ea01a46 Tell Git to export '.gitattributes'
          4f39791b Glob: Add explicit assignment operator to Message member
          c2387a4b DynamicLoader: Fix CloseLibrary for failed OpenLibrary on HP-UX

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..248786e
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,16 @@
+.git*            export-ignore
+.gitattributes  -export-ignore
+
+/GitSetup        export-ignore
+/SetupForDevelopment.sh  export-ignore  eol=lf
+
+/CONTRIBUTING.rst conflict-marker-size=78
+
+*.c              whitespace=tab-in-indent,no-lf-at-eof
+*.h              whitespace=tab-in-indent,no-lf-at-eof
+*.h.in           whitespace=tab-in-indent,no-lf-at-eof
+*.cxx            whitespace=tab-in-indent,no-lf-at-eof
+*.hxx            whitespace=tab-in-indent,no-lf-at-eof
+*.hxx.in         whitespace=tab-in-indent,no-lf-at-eof
+*.txt            whitespace=tab-in-indent,no-lf-at-eof
+*.cmake          whitespace=tab-in-indent,no-lf-at-eof
diff --git a/DynamicLoader.cxx b/DynamicLoader.cxx
index 66c7d57..a776f97 100644
--- a/DynamicLoader.cxx
+++ b/DynamicLoader.cxx
@@ -48,6 +48,10 @@ DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string&
 //----------------------------------------------------------------------------
 int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
 {
+  if (!lib)
+    {
+    return 0;
+    }
   return !shl_unload(lib);
 }
 
diff --git a/Glob.hxx.in b/Glob.hxx.in
index 39b7ce7..5239ccd 100644
--- a/Glob.hxx.in
+++ b/Glob.hxx.in
@@ -59,6 +59,12 @@ public:
       type(msg.type),
       content(msg.content)
     {}
+    Message& operator=(Message const& msg)
+      {
+      this->type = msg.type;
+      this->content = msg.content;
+      return *this;
+      }
   };
 
   typedef kwsys_stl::vector<Message> GlobMessages;

-----------------------------------------------------------------------

Summary of changes:
 Source/kwsys/.gitattributes    |   16 ++
 Source/kwsys/DynamicLoader.cxx |    4 +
 Source/kwsys/Glob.hxx.in       |    6 +
 Source/kwsys/ProcessUNIX.c     |  355 +++++++++++++------------
 Source/kwsys/ProcessWin32.c    |  559 ++++++++++++++++++----------------------
 5 files changed, 472 insertions(+), 468 deletions(-)
 create mode 100644 Source/kwsys/.gitattributes


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list