BUG: don't close the pipes too early

This commit is contained in:
Bill Hoffman 2004-09-08 10:41:54 -04:00
parent b5bdf2cb0a
commit 815c1cad70
2 changed files with 83 additions and 71 deletions

View File

@ -483,19 +483,26 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
int mode, int mode,
int n) int n)
{ {
HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, HANDLE hProcess;
hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
SECURITY_ATTRIBUTES saAttr; SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess; BOOL fSuccess;
int fd1, fd2, fd3; int fd1, fd2, fd3;
this->hChildStdinRd = 0;
this->hChildStdinWr = 0;
this->hChildStdoutRd = 0;
this->hChildStdoutWr = 0;
this->hChildStderrRd = 0;
this->hChildStderrWr = 0;
this->hChildStdinWrDup = 0;
this->hChildStdoutRdDup = 0;
this->hChildStderrRdDup = 0;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE; saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL; saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) if (!CreatePipe(&this->hChildStdinRd, &this->hChildStdinWr, &saAttr, 0))
{ {
m_Output += "CreatePipeError\n"; m_Output += "CreatePipeError\n";
return false; return false;
@ -505,8 +512,8 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
* the inheritance properties to FALSE. Otherwise, the child inherits * the inheritance properties to FALSE. Otherwise, the child inherits
* the these handles; resulting in non-closeable handles to the pipes * the these handles; resulting in non-closeable handles to the pipes
* being created. */ * being created. */
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, 0, GetCurrentProcess(), &this->hChildStdinWrDup, 0,
FALSE, FALSE,
DUPLICATE_SAME_ACCESS); DUPLICATE_SAME_ACCESS);
if (!fSuccess) if (!fSuccess)
@ -520,14 +527,14 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
that we're using. */ that we're using. */
CloseHandle(hChildStdinWr); CloseHandle(hChildStdinWr);
if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) if (!CreatePipe(&this->hChildStdoutRd, &this->hChildStdoutWr, &saAttr, 0))
{ {
m_Output += "CreatePipeError\n"; m_Output += "CreatePipeError\n";
return false; return false;
} }
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup, 0, GetCurrentProcess(), &this->hChildStdoutRdDup, 0,
FALSE, DUPLICATE_SAME_ACCESS); FALSE, DUPLICATE_SAME_ACCESS);
if (!fSuccess) if (!fSuccess)
{ {
@ -541,16 +548,16 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
if (n != POPEN_4) if (n != POPEN_4)
{ {
if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0)) if (!CreatePipe(&this->hChildStderrRd, &this->hChildStderrWr, &saAttr, 0))
{ {
m_Output += "CreatePipeError\n"; m_Output += "CreatePipeError\n";
return false; return false;
} }
fSuccess = DuplicateHandle(GetCurrentProcess(), fSuccess = DuplicateHandle(GetCurrentProcess(),
hChildStderrRd, this->hChildStderrRd,
GetCurrentProcess(), GetCurrentProcess(),
&hChildStderrRdDup, 0, &this->hChildStderrRdDup, 0,
FALSE, DUPLICATE_SAME_ACCESS); FALSE, DUPLICATE_SAME_ACCESS);
if (!fSuccess) if (!fSuccess)
{ {
m_Output += "DuplicateHandleError\n"; m_Output += "DuplicateHandleError\n";
@ -568,14 +575,14 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
{ {
case _O_WRONLY | _O_TEXT: case _O_WRONLY | _O_TEXT:
/* Case for writing to child Stdin in text mode. */ /* Case for writing to child Stdin in text mode. */
fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode); fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
/* We don't care about these pipes anymore, /* We don't care about these pipes anymore,
so close them. */ so close them. */
break; break;
case _O_RDONLY | _O_TEXT: case _O_RDONLY | _O_TEXT:
/* Case for reading from child Stdout in text mode. */ /* Case for reading from child Stdout in text mode. */
fd1 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode); fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
/* We don't care about these pipes anymore, /* We don't care about these pipes anymore,
so close them. */ so close them. */
break; break;
@ -583,14 +590,14 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
case _O_RDONLY | _O_BINARY: case _O_RDONLY | _O_BINARY:
/* Case for readinig from child Stdout in /* Case for readinig from child Stdout in
binary mode. */ binary mode. */
fd1 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode); fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
/* We don't care about these pipes anymore, /* We don't care about these pipes anymore,
so close them. */ so close them. */
break; break;
case _O_WRONLY | _O_BINARY: case _O_WRONLY | _O_BINARY:
/* Case for writing to child Stdin in binary mode. */ /* Case for writing to child Stdin in binary mode. */
fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode); fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
/* We don't care about these pipes anymore, /* We don't care about these pipes anymore,
so close them. */ so close them. */
break; break;
@ -601,17 +608,17 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
case POPEN_4: case POPEN_4:
if ( 1 ) if ( 1 )
{ {
fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode); fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
fd2 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode); fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
break; break;
} }
case POPEN_3: case POPEN_3:
if ( 1) if ( 1)
{ {
fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode); fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
fd2 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode); fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
fd3 = _open_osfhandle(TO_INTPTR(hChildStderrRdDup), mode); fd3 = _open_osfhandle(TO_INTPTR(this->hChildStderrRdDup), mode);
break; break;
} }
} }
@ -621,9 +628,9 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
if (!RealPopenCreateProcess(cmdstring, if (!RealPopenCreateProcess(cmdstring,
path, path,
m_ConsoleSpawn.c_str(), m_ConsoleSpawn.c_str(),
hChildStdinRd, this->hChildStdinRd,
hChildStdoutWr, this->hChildStdoutWr,
hChildStdoutWr, this->hChildStdoutWr,
&hProcess, m_HideWindows, &hProcess, m_HideWindows,
m_Output)) m_Output))
return 0; return 0;
@ -633,9 +640,9 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
if (!RealPopenCreateProcess(cmdstring, if (!RealPopenCreateProcess(cmdstring,
path, path,
m_ConsoleSpawn.c_str(), m_ConsoleSpawn.c_str(),
hChildStdinRd, this->hChildStdinRd,
hChildStdoutWr, this->hChildStdoutWr,
hChildStderrWr, this->hChildStderrWr,
&hProcess, m_HideWindows, &hProcess, m_HideWindows,
m_Output)) m_Output))
return 0; return 0;
@ -658,39 +665,6 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
* make sure that no handles to the write end of the output pipe * make sure that no handles to the write end of the output pipe
* are maintained in this process or else the pipe will not close * are maintained in this process or else the pipe will not close
* when the child process exits and the ReadFile will hang. */ * when the child process exits and the ReadFile will hang. */
if (!CloseHandle(hChildStdinRd))
{
m_Output += "CloseHandleError\n";
return false;
}
if(!CloseHandle(hChildStdoutRdDup))
{
m_Output += "CloseHandleError\n";
return false;
}
if(!CloseHandle(hChildStderrRdDup))
{
m_Output += "CloseHandleError\n";
return false;
}
if(!CloseHandle(hChildStdinWrDup))
{
m_Output += "CloseHandleError\n";
return false;
}
if (!CloseHandle(hChildStdoutWr))
{
m_Output += "CloseHandleError\n";
return false;
}
if ((n != 4) && (!CloseHandle(hChildStderrWr)))
{
m_Output += "CloseHandleError\n";
return false;
}
m_ProcessHandle = hProcess; m_ProcessHandle = hProcess;
if ( fd1 >= 0 ) if ( fd1 >= 0 )
{ {
@ -832,6 +806,40 @@ bool cmWin32ProcessExecution::PrivateClose(int /* timeout */)
CloseHandle(hProcess); CloseHandle(hProcess);
m_ExitValue = result; m_ExitValue = result;
m_Output += output; m_Output += output;
if (this->hChildStdinRd && !CloseHandle(this->hChildStdinRd))
{
m_Output += "CloseHandleError\n";
return false;
}
if(this->hChildStdoutRdDup && !CloseHandle(this->hChildStdoutRdDup))
{
m_Output += "CloseHandleError\n";
return false;
}
if(this->hChildStderrRdDup && !CloseHandle(this->hChildStderrRdDup))
{
m_Output += "CloseHandleError\n";
return false;
}
if(this->hChildStdinWrDup && !CloseHandle(this->hChildStdinWrDup))
{
m_Output += "CloseHandleError\n";
return false;
}
if (this->hChildStdoutWr && !CloseHandle(this->hChildStdoutWr))
{
m_Output += "CloseHandleError\n";
return false;
}
if (this->hChildStderrWr && !CloseHandle(this->hChildStderrWr))
{
m_Output += "CloseHandleError\n";
return false;
}
if ( result < 0 ) if ( result < 0 )
{ {
return false; return false;

View File

@ -143,12 +143,16 @@ private:
bool PrivateClose(int timeout); bool PrivateClose(int timeout);
HANDLE m_ProcessHandle; HANDLE m_ProcessHandle;
HANDLE hChildStdinRd;
HANDLE hChildStdinWr;
HANDLE hChildStdoutRd;
HANDLE hChildStdoutWr;
HANDLE hChildStderrRd;
HANDLE hChildStderrWr;
HANDLE hChildStdinWrDup;
HANDLE hChildStdoutRdDup;
HANDLE hChildStderrRdDup;
// Comment this out. Maybe we will need it in the future.
// file IO access to the process might be cool.
// FILE* m_StdIn;
// FILE* m_StdOut;
// FILE* m_StdErr;
int m_pStdIn; int m_pStdIn;
int m_pStdOut; int m_pStdOut;