From 34fceb50156f8a907b3c8ce74e0b3ec33ffa30b4 Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Mon, 4 May 2015 14:10:41 -0400
Subject: [PATCH] Process: Add option to merge stdout/stderr

When enabled, ignore all stderr pipe configuration options and
just give the child a copy of stdout as its stderr.

Change-Id: I87a64657cc701b706da78f7bfc56ad0071383372
---
 Process.h.in   | 9 +++++++++
 ProcessUNIX.c  | 9 +++++++--
 ProcessWin32.c | 9 +++++++--
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/Process.h.in b/Process.h.in
index c5995eac..e35939f3 100644
--- a/Process.h.in
+++ b/Process.h.in
@@ -36,6 +36,7 @@
 # define kwsysProcess_SetPipeShared       kwsys_ns(Process_SetPipeShared)
 # define kwsysProcess_Option_Detach       kwsys_ns(Process_Option_Detach)
 # define kwsysProcess_Option_HideWindow   kwsys_ns(Process_Option_HideWindow)
+# define kwsysProcess_Option_MergeOutput  kwsys_ns(Process_Option_MergeOutput)
 # define kwsysProcess_Option_Verbatim     kwsys_ns(Process_Option_Verbatim)
 # define kwsysProcess_GetOption           kwsys_ns(Process_GetOption)
 # define kwsysProcess_SetOption           kwsys_ns(Process_SetOption)
@@ -186,6 +187,12 @@ kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe,
  *         0 = No (default)
  *         1 = Yes
  *
+ *  kwsysProcess_Option_MergeOutput = Whether to merge stdout/stderr.
+ *                                    No content will be returned as stderr.
+ *                                    Any actual stderr will be on stdout.
+ *         0 = No (default)
+ *         1 = Yes
+ *
  *  kwsysProcess_Option_Verbatim = Whether SetCommand and AddCommand
  *                                 should treat the first argument
  *                                 as a verbatim command line
@@ -200,6 +207,7 @@ enum kwsysProcess_Option_e
 {
   kwsysProcess_Option_HideWindow,
   kwsysProcess_Option_Detach,
+  kwsysProcess_Option_MergeOutput,
   kwsysProcess_Option_Verbatim
 };
 
@@ -384,6 +392,7 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
 #  undef kwsysProcess_SetPipeShared
 #  undef kwsysProcess_Option_Detach
 #  undef kwsysProcess_Option_HideWindow
+#  undef kwsysProcess_Option_MergeOutput
 #  undef kwsysProcess_Option_Verbatim
 #  undef kwsysProcess_GetOption
 #  undef kwsysProcess_SetOption
diff --git a/ProcessUNIX.c b/ProcessUNIX.c
index 68722c2a..0393a6de 100644
--- a/ProcessUNIX.c
+++ b/ProcessUNIX.c
@@ -234,6 +234,9 @@ struct kwsysProcess_s
   /* Whether to treat command lines as verbatim.  */
   int Verbatim;
 
+  /* Whether to merge stdout/stderr of the child.  */
+  int MergeOutput;
+
   /* Time at which the child started.  Negative for no timeout.  */
   kwsysProcessTime StartTime;
 
@@ -644,6 +647,7 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
   switch(optionId)
     {
     case kwsysProcess_Option_Detach: return cp->OptionDetach;
+    case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
     case kwsysProcess_Option_Verbatim: return cp->Verbatim;
     default: return 0;
     }
@@ -660,6 +664,7 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
   switch(optionId)
     {
     case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
+    case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
     case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
     default: break;
     }
@@ -997,7 +1002,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
       nextStdIn = p[0];
       si.StdOut = p[1];
       }
-    si.StdErr = cp->PipeChildStd[2];
+    si.StdErr = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
 
     {
     int res = kwsysProcessCreate(cp, i, &si);
@@ -1011,7 +1016,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
       {
       kwsysProcessCleanupDescriptor(&si.StdOut);
       }
-    if (si.StdErr != cp->PipeChildStd[2])
+    if (si.StdErr != cp->PipeChildStd[2] && !cp->MergeOutput)
       {
       kwsysProcessCleanupDescriptor(&si.StdErr);
       }
diff --git a/ProcessWin32.c b/ProcessWin32.c
index da1bc150..f6301718 100644
--- a/ProcessWin32.c
+++ b/ProcessWin32.c
@@ -226,6 +226,9 @@ struct kwsysProcess_s
   /* Whether to treat command lines as verbatim.  */
   int Verbatim;
 
+  /* Whether to merge stdout/stderr of the child.  */
+  int MergeOutput;
+
   /* Mutex to protect the shared index used by threads to report data.  */
   HANDLE SharedIndexMutex;
 
@@ -806,6 +809,7 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int 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;
     default: return 0;
     }
@@ -823,6 +827,7 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
     {
     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;
     default: break;
     }
@@ -1086,7 +1091,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
       nextStdInput = p[0];
       si.hStdOutput = p[1];
       }
-    si.hStdError = cp->PipeChildStd[2];
+    si.hStdError = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
 
     {
     int res = kwsysProcessCreate(cp, i, &si);
@@ -1100,7 +1105,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
       {
       kwsysProcessCleanupHandle(&si.hStdOutput);
       }
-    if (si.hStdError != cp->PipeChildStd[2])
+    if (si.hStdError != cp->PipeChildStd[2] && !cp->MergeOutput)
       {
       kwsysProcessCleanupHandle(&si.hStdError);
       }
-- 
GitLab