BUG: don't close the pipes too early
This commit is contained in:
parent
b5bdf2cb0a
commit
815c1cad70
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue