Also avoid inheriting std{out,err} pipes in wxMSW wxExecute().

Fix possible deadlock in the child which would happen if it continued to
produce output after the parent, that used wxExecute() with IO redirection to
launch it, exits.

Do this by preventing the child from inheriting the read ends of the standard
output and error pipes, just as it was already done for the write end of the
standard input pipe.

Closes #16898.
This commit is contained in:
Richard Broker 2015-03-12 13:29:09 +01:00 committed by Vadim Zeitlin
parent a934346614
commit 009abf22b7

View File

@ -725,16 +725,24 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
si.hStdOutput = pipeOut[wxPipe::Write];
si.hStdError = pipeErr[wxPipe::Write];
// We must set the handle to the side of the pipes that we won't use in
// the child to be non-inheritable. We must do this before launching
// We must set the handles to those sides of std* pipes that we won't
// in the child to be non-inheritable. We must do this before launching
// the child process as otherwise these handles will be inherited by
// the child which will never close them and so the pipe will not
// return ERROR_BROKEN_PIPE if the parent or child exits unexpectedly
// causing the remaining process to potentially become deadlocked in
// ReadFile().
// ReadFile() or WriteFile().
if ( !::SetHandleInformation(pipeIn[wxPipe::Write],
HANDLE_FLAG_INHERIT, 0) )
wxLogLastError(wxT("SetHandleInformation(pipeIn)"));
if ( !::SetHandleInformation(pipeOut[wxPipe::Read],
HANDLE_FLAG_INHERIT, 0) )
wxLogLastError(wxT("SetHandleInformation(pipeOut)"));
if ( !::SetHandleInformation(pipeErr[wxPipe::Read],
HANDLE_FLAG_INHERIT, 0) )
wxLogLastError(wxT("SetHandleInformation(pipeErr)"));
}
#endif // wxUSE_STREAMS