summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/ProcessWin32.c
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2006-10-03 13:10:03 (GMT)
committerBrad King <brad.king@kitware.com>2006-10-03 13:10:03 (GMT)
commit6eef6638a5ca1c76b7d51e9d71bc5ef9c96875e0 (patch)
tree06047abad6d96cf164aaf9266257b5098cc9cc18 /Source/kwsys/ProcessWin32.c
parent9d566ee8bd6e1c93aa083aac496e2335891cccec (diff)
downloadCMake-6eef6638a5ca1c76b7d51e9d71bc5ef9c96875e0.zip
CMake-6eef6638a5ca1c76b7d51e9d71bc5ef9c96875e0.tar.gz
CMake-6eef6638a5ca1c76b7d51e9d71bc5ef9c96875e0.tar.bz2
ENH: Added Process_SetPipeNative method to allow user code to override the pipes connected to the child pipeline.
Diffstat (limited to 'Source/kwsys/ProcessWin32.c')
-rw-r--r--Source/kwsys/ProcessWin32.c109
1 files changed, 107 insertions, 2 deletions
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index 4f50d36..8f8aca6 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -105,6 +105,8 @@ static int kwsysProcessCreate(kwsysProcess* cp, int index,
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 kwsysProcessCleanupHandle(PHANDLE h);
static void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle);
static void kwsysProcessCleanup(kwsysProcess* cp, int error);
@@ -247,6 +249,11 @@ struct kwsysProcess_s
int PipeSharedSTDOUT;
int PipeSharedSTDERR;
+ /* Native pipes provided by the user. */
+ HANDLE PipeNativeSTDIN[2];
+ HANDLE PipeNativeSTDOUT[2];
+ HANDLE PipeNativeSTDERR[2];
+
/* Handle to automatically delete the Win9x forwarding executable. */
HANDLE Win9xHandle;
@@ -790,9 +797,11 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
strcpy(*pfile, file);
}
- /* If we are redirecting the pipe, do not share it. */
+ /* 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);
}
@@ -815,10 +824,51 @@ void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
default: return;
}
- /* If we are sharing the pipe, do not redirect it to a file. */
+ /* 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);
}
}
@@ -1020,6 +1070,21 @@ void kwsysProcess_Execute(kwsysProcess* cp)
}
}
+ /* 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])
+ {
+ if(!kwsysProcessSetupPipeNative(&si.StartupInfo.hStdError,
+ cp->PipeNativeSTDERR, 1))
+ {
+ kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
+ STD_ERROR_HANDLE);
+ return;
+ }
+ }
+
/* Create the pipeline of processes. */
{
HANDLE readEnd = 0;
@@ -1622,6 +1687,15 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
return 0;
}
}
+ else if(cp->PipeNativeSTDIN[0])
+ {
+ /* Use the provided native pipe. */
+ if(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdInput,
+ cp->PipeNativeSTDIN, 0))
+ {
+ return 0;
+ }
+ }
else
{
/* Explicitly give the child no stdin. */
@@ -1680,6 +1754,18 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
}
}
+ /* 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(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdOutput,
+ cp->PipeNativeSTDOUT, 1))
+ {
+ return 0;
+ }
+ }
+
/* Create the child process. */
{
BOOL r;
@@ -1929,6 +2015,25 @@ int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle)
}
/*--------------------------------------------------------------------------*/
+int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2], int isWrite)
+{
+ /* Close the existing inherited 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;
+}
+
+/*--------------------------------------------------------------------------*/
/* Close the given handle if it is open. Reset its value to 0. */
void kwsysProcessCleanupHandle(PHANDLE h)