diff options
author | Brad King <brad.king@kitware.com> | 2003-12-16 22:20:01 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2003-12-16 22:20:01 (GMT) |
commit | 802601b6067198e175b34cb7a5133f5b491b4f2f (patch) | |
tree | f952856bbb5a759444c5147ea9634673faf4f06f /Source/kwsys/ProcessUNIX.c | |
parent | ab0a30e2b3f2fc3fc8d3eacddd7f7e2210faa426 (diff) | |
download | CMake-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/kwsys/ProcessUNIX.c')
-rw-r--r-- | Source/kwsys/ProcessUNIX.c | 95 |
1 files changed, 86 insertions, 9 deletions
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 |