Use SetHandleInformation() to make handle non-inheritable in wxMSW.
Simplify the code in wxExecute() by using SetHandleInformation() to make the handle non-inheritable instead of duplicating it to achieve the same goal (the old code worked under Windows 9x too, unlike the new one, but we don't care about them any more). See #16898.
This commit is contained in:
committed by
Vadim Zeitlin
parent
96a8240e87
commit
a934346614
@@ -694,9 +694,6 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
|
|||||||
#if wxUSE_STREAMS && !defined(__WXWINCE__)
|
#if wxUSE_STREAMS && !defined(__WXWINCE__)
|
||||||
wxPipe pipeIn, pipeOut, pipeErr;
|
wxPipe pipeIn, pipeOut, pipeErr;
|
||||||
|
|
||||||
// we'll save here the copy of pipeIn[Write]
|
|
||||||
HANDLE hpipeStdinWrite = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
// open the pipes to which child process IO will be redirected if needed
|
// open the pipes to which child process IO will be redirected if needed
|
||||||
if ( handler && handler->IsRedirected() )
|
if ( handler && handler->IsRedirected() )
|
||||||
{
|
{
|
||||||
@@ -728,27 +725,16 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
|
|||||||
si.hStdOutput = pipeOut[wxPipe::Write];
|
si.hStdOutput = pipeOut[wxPipe::Write];
|
||||||
si.hStdError = pipeErr[wxPipe::Write];
|
si.hStdError = pipeErr[wxPipe::Write];
|
||||||
|
|
||||||
// we must duplicate the handle to the write side of stdin pipe to make
|
// We must set the handle to the side of the pipes that we won't use in
|
||||||
// it non inheritable: indeed, we must close the writing end of pipeIn
|
// the child to be non-inheritable. We must do this before launching
|
||||||
// before launching the child process as otherwise this handle will be
|
// the child process as otherwise these handles will be inherited by
|
||||||
// inherited by the child which will never close it and so the pipe
|
// the child which will never close them and so the pipe will not
|
||||||
// will never be closed and the child will be left stuck in ReadFile()
|
// return ERROR_BROKEN_PIPE if the parent or child exits unexpectedly
|
||||||
HANDLE pipeInWrite = pipeIn.Detach(wxPipe::Write);
|
// causing the remaining process to potentially become deadlocked in
|
||||||
if ( !::DuplicateHandle
|
// ReadFile().
|
||||||
(
|
if ( !::SetHandleInformation(pipeIn[wxPipe::Write],
|
||||||
::GetCurrentProcess(),
|
HANDLE_FLAG_INHERIT, 0) )
|
||||||
pipeInWrite,
|
wxLogLastError(wxT("SetHandleInformation(pipeIn)"));
|
||||||
::GetCurrentProcess(),
|
|
||||||
&hpipeStdinWrite,
|
|
||||||
0, // desired access: unused here
|
|
||||||
FALSE, // not inherited
|
|
||||||
DUPLICATE_SAME_ACCESS // same access as for src handle
|
|
||||||
) )
|
|
||||||
{
|
|
||||||
wxLogLastError(wxT("DuplicateHandle"));
|
|
||||||
}
|
|
||||||
|
|
||||||
::CloseHandle(pipeInWrite);
|
|
||||||
}
|
}
|
||||||
#endif // wxUSE_STREAMS
|
#endif // wxUSE_STREAMS
|
||||||
|
|
||||||
@@ -889,6 +875,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
|
|||||||
// close the other handles too
|
// close the other handles too
|
||||||
if ( redirect )
|
if ( redirect )
|
||||||
{
|
{
|
||||||
|
::CloseHandle(pipeIn.Detach(wxPipe::Write));
|
||||||
::CloseHandle(pipeOut.Detach(wxPipe::Read));
|
::CloseHandle(pipeOut.Detach(wxPipe::Read));
|
||||||
::CloseHandle(pipeErr.Detach(wxPipe::Read));
|
::CloseHandle(pipeErr.Detach(wxPipe::Read));
|
||||||
}
|
}
|
||||||
@@ -913,7 +900,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
|
|||||||
wxPipeInputStream *
|
wxPipeInputStream *
|
||||||
errStream = new wxPipeInputStream(pipeErr.Detach(wxPipe::Read));
|
errStream = new wxPipeInputStream(pipeErr.Detach(wxPipe::Read));
|
||||||
wxPipeOutputStream *
|
wxPipeOutputStream *
|
||||||
inStream = new wxPipeOutputStream(hpipeStdinWrite);
|
inStream = new wxPipeOutputStream(pipeIn.Detach(wxPipe::Write));
|
||||||
|
|
||||||
handler->SetPipeStreams(outStream, inStream, errStream);
|
handler->SetPipeStreams(outStream, inStream, errStream);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user