summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2003-12-16 22:20:01 (GMT)
committerBrad King <brad.king@kitware.com>2003-12-16 22:20:01 (GMT)
commit802601b6067198e175b34cb7a5133f5b491b4f2f (patch)
treef952856bbb5a759444c5147ea9634673faf4f06f /Source
parentab0a30e2b3f2fc3fc8d3eacddd7f7e2210faa426 (diff)
downloadCMake-802601b6067198e175b34cb7a5133f5b491b4f2f.zip
CMake-802601b6067198e175b34cb7a5133f5b491b4f2f.tar.gz
CMake-802601b6067198e175b34cb7a5133f5b491b4f2f.tar.bz2
ENH: Added SetPipeShared method to allow stdout and stderr pipes to be shared with the parent process.
Diffstat (limited to 'Source')
-rw-r--r--Source/kwsys/Process.h.in10
-rw-r--r--Source/kwsys/ProcessUNIX.c95
-rw-r--r--Source/kwsys/ProcessWin32.c81
3 files changed, 171 insertions, 15 deletions
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
index 944d92c..83e3060 100644
--- a/Source/kwsys/Process.h.in
+++ b/Source/kwsys/Process.h.in
@@ -31,6 +31,7 @@
#define kwsysProcess_SetTimeout kwsys(Process_SetTimeout)
#define kwsysProcess_SetWorkingDirectory kwsys(Process_SetWorkingDirectory)
#define kwsysProcess_SetPipeFile kwsys(Process_SetPipeFile)
+#define kwsysProcess_SetPipeShared kwsys(Process_SetPipeShared)
#define kwsysProcess_Option_HideWindow kwsys(Process_Option_HideWindow)
#define kwsysProcess_GetOption kwsys(Process_GetOption)
#define kwsysProcess_SetOption kwsys(Process_SetOption)
@@ -130,6 +131,14 @@ kwsysEXPORT int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe,
const char* file);
/**
+ * Set whether the given pipe in the child is shared with the parent
+ * process. The default is no for Pipe_STDOUT and Pipe_STDERR and yes
+ * for Pipe_STDIN.
+ */
+kwsysEXPORT void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe,
+ int shared);
+
+/**
* Get/Set a platform-specific option. Possible options are:
*
* kwsysProcess_Option_HideWindow = Whether to hide window on Windows.
@@ -301,6 +310,7 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
# undef kwsysProcess_SetTimeout
# undef kwsysProcess_SetWorkingDirectory
# undef kwsysProcess_SetPipeFile
+# undef kwsysProcess_SetPipeShared
# undef kwsysProcess_Option_HideWindow
# undef kwsysProcess_GetOption
# undef kwsysProcess_SetOption
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index ec1e9f8..2abc8e1 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -169,6 +169,11 @@ struct kwsysProcess_s
char* PipeFileSTDOUT;
char* PipeFileSTDERR;
+ /* Whether each pipe is shared with the parent process. */
+ int PipeSharedSTDIN;
+ int PipeSharedSTDOUT;
+ int PipeSharedSTDERR;
+
/* The real working directory of this process. */
int RealWorkingDirectoryLength;
char* RealWorkingDirectory;
@@ -184,7 +189,13 @@ kwsysProcess* kwsysProcess_New()
return 0;
}
memset(cp, 0, sizeof(kwsysProcess));
+
+ /* Share stdin with the parent process by default. */
+ cp->PipeSharedSTDIN = 1;
+
+ /* Set initial status. */
cp->State = kwsysProcess_State_Starting;
+
return cp;
}
@@ -393,10 +404,39 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
}
strcpy(*pfile, file);
}
+
+ /* If we are redirecting the pipe, do not share it. */
+ if(*pfile)
+ {
+ kwsysProcess_SetPipeShared(cp, pipe, 0);
+ }
return 1;
}
/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
+{
+ if(!cp)
+ {
+ return;
+ }
+
+ switch(pipe)
+ {
+ case kwsysProcess_Pipe_STDIN: cp->PipeSharedSTDIN = shared?1:0; break;
+ case kwsysProcess_Pipe_STDOUT: cp->PipeSharedSTDOUT = shared?1:0; break;
+ case kwsysProcess_Pipe_STDERR: cp->PipeSharedSTDERR = shared?1:0; break;
+ default: return;
+ }
+
+ /* If we are sharing the pipe, do not redirect it to a file. */
+ if(shared)
+ {
+ kwsysProcess_SetPipeFile(cp, pipe, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
{
(void)cp;
@@ -545,6 +585,14 @@ void kwsysProcess_Execute(kwsysProcess* cp)
}
}
+ /* 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)
+ {
+ kwsysProcessCleanupDescriptor(&si.StdErr);
+ si.StdErr = 2;
+ }
/* The timeout period starts now. */
cp->StartTime = kwsysProcessTimeGetCurrent();
@@ -553,7 +601,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
/* Create the pipeline of processes. */
{
- int readEnd = 0;
+ int readEnd = -1;
for(i=0; i < cp->NumberOfCommands; ++i)
{
if(!kwsysProcessCreate(cp, i, &si, &readEnd))
@@ -562,13 +610,19 @@ void kwsysProcess_Execute(kwsysProcess* cp)
/* Release resources that may have been allocated for this
process before an error occurred. */
- if(i > 0 || si.StdIn > 0)
+ kwsysProcessCleanupDescriptor(&readEnd);
+ if(si.StdIn != 0)
{
kwsysProcessCleanupDescriptor(&si.StdIn);
}
- kwsysProcessCleanupDescriptor(&readEnd);
- kwsysProcessCleanupDescriptor(&si.StdOut);
- kwsysProcessCleanupDescriptor(&si.StdErr);
+ if(si.StdOut != 1)
+ {
+ kwsysProcessCleanupDescriptor(&si.StdOut);
+ }
+ if(si.StdErr != 2)
+ {
+ kwsysProcessCleanupDescriptor(&si.StdErr);
+ }
kwsysProcessCleanupDescriptor(&si.TermPipe);
kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]);
kwsysProcessCleanupDescriptor(&si.ErrorPipe[1]);
@@ -1106,10 +1160,14 @@ static int kwsysProcessCreate(kwsysProcess* cp, int index,
return 0;
}
}
- else
+ else if(cp->PipeSharedSTDIN)
{
si->StdIn = 0;
}
+ else
+ {
+ si->StdIn = -1;
+ }
/* Setup the process's stdout. */
{
@@ -1140,6 +1198,15 @@ static int kwsysProcessCreate(kwsysProcess* cp, int index,
}
}
+ /* Replace the stdout pipe with the parent's if requested. In this
+ case the select call will report that stderr is closed
+ immediately. */
+ if(index == cp->NumberOfCommands-1 && cp->PipeSharedSTDOUT)
+ {
+ kwsysProcessCleanupDescriptor(&si->StdOut);
+ si->StdOut = 1;
+ }
+
/* Create the error reporting pipe. */
if(pipe(si->ErrorPipe) < 0)
{
@@ -1165,12 +1232,22 @@ static int kwsysProcessCreate(kwsysProcess* cp, int index,
close(si->ErrorPipe[0]);
/* Setup the stdin, stdout, and stderr pipes. */
- if(index > 0 || si->StdIn > 0)
+ if(si->StdIn > 0)
{
dup2(si->StdIn, 0);
}
- dup2(si->StdOut, 1);
- dup2(si->StdErr, 2);
+ else if(si->StdIn < 0)
+ {
+ close(0);
+ }
+ if(si->StdOut != 1)
+ {
+ dup2(si->StdOut, 1);
+ }
+ if(si->StdErr != 2)
+ {
+ 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
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index d1d3c5e..c710fac 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -184,6 +184,11 @@ struct kwsysProcess_s
char* PipeFileSTDOUT;
char* PipeFileSTDERR;
+ /* Whether each pipe is shared with the parent process. */
+ int PipeSharedSTDIN;
+ int PipeSharedSTDOUT;
+ int PipeSharedSTDERR;
+
/* Handle to automatically delete the Win9x forwarding executable. */
HANDLE Win9xHandle;
@@ -264,6 +269,9 @@ kwsysProcess* kwsysProcess_New()
}
ZeroMemory(cp, sizeof(*cp));
+ /* Share stdin with the parent process by default. */
+ cp->PipeSharedSTDIN = 1;
+
/* Set initial status. */
cp->State = kwsysProcess_State_Starting;
@@ -805,10 +813,40 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
}
strcpy(*pfile, file);
}
+
+ /* If we are redirecting the pipe, do not share it. */
+ if(*pfile)
+ {
+ kwsysProcess_SetPipeShared(cp, pipe, 0);
+ }
+
return 1;
}
/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
+{
+ if(!cp)
+ {
+ return;
+ }
+
+ switch(pipe)
+ {
+ case kwsysProcess_Pipe_STDIN: cp->PipeSharedSTDIN = shared?1:0; break;
+ case kwsysProcess_Pipe_STDOUT: cp->PipeSharedSTDOUT = shared?1:0; break;
+ case kwsysProcess_Pipe_STDERR: cp->PipeSharedSTDERR = shared?1:0; break;
+ default: return;
+ }
+
+ /* If we are sharing the pipe, do not redirect it to a file. */
+ if(shared)
+ {
+ kwsysProcess_SetPipeFile(cp, pipe, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
{
if(!cp)
@@ -973,6 +1011,15 @@ void kwsysProcess_Execute(kwsysProcess* cp)
}
}
+ /* 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)
+ {
+ kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
+ si.StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ }
+
/* Create the pipeline of processes. */
{
HANDLE readEnd = 0;
@@ -989,12 +1036,18 @@ void kwsysProcess_Execute(kwsysProcess* cp)
/* Release resources that may have been allocated for this
process before an error occurred. */
kwsysProcessCleanupHandle(&readEnd);
- if(i > 0)
+ if(si.StartupInfo.hStdInput != GetStdHandle(STD_INPUT_HANDLE))
{
kwsysProcessCleanupHandle(&si.StartupInfo.hStdInput);
}
- kwsysProcessCleanupHandle(&si.StartupInfo.hStdOutput);
- kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
+ if(si.StartupInfo.hStdOutput != GetStdHandle(STD_OUTPUT_HANDLE))
+ {
+ kwsysProcessCleanupHandle(&si.StartupInfo.hStdOutput);
+ }
+ if(si.StartupInfo.hStdOutput != GetStdHandle(STD_ERROR_HANDLE))
+ {
+ kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
+ }
kwsysProcessCleanupHandle(&si.ErrorPipeRead);
kwsysProcessCleanupHandle(&si.ErrorPipeWrite);
return;
@@ -1533,10 +1586,14 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
}
si->StartupInfo.hStdInput = fin;
}
- else
+ else if(cp->PipeSharedSTDIN)
{
si->StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
}
+ else
+ {
+ si->StartupInfo.hStdInput = INVALID_HANDLE_VALUE;
+ }
/* Setup the process's stdout. */
{
@@ -1578,6 +1635,15 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
}
}
+ /* Replace the stdout pipe 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)
+ {
+ kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
+ si->StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ }
+
/* Create the child process. */
{
BOOL r;
@@ -1678,8 +1744,11 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput);
}
- /* The parent process does not need the inhertied pipe write end. */
- kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
+ if(si->StartupInfo.hStdOutput != GetStdHandle(STD_OUTPUT_HANDLE))
+ {
+ /* The parent process does not need the inhertied pipe write end. */
+ kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
+ }
return 1;
}