X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8b33ae2d5a6ed14ab4b89391b2a1cb5e9f164e90..5e1febfacedfb966daaf4050c293e0833593df82:/src/msw/utilsexc.cpp diff --git a/src/msw/utilsexc.cpp b/src/msw/utilsexc.cpp index 411eaeaf44..453b7efc5d 100644 --- a/src/msw/utilsexc.cpp +++ b/src/msw/utilsexc.cpp @@ -158,7 +158,7 @@ protected: wxPipeInputStream::wxPipeInputStream(HANDLE hInput) { m_hInput = hInput; -} +} wxPipeInputStream::~wxPipeInputStream() { @@ -186,7 +186,7 @@ size_t wxPipeInputStream::OnSysRead(void *buffer, size_t len) wxPipeOutputStream::wxPipeOutputStream(HANDLE hOutput) { m_hOutput = hOutput; -} +} wxPipeOutputStream::~wxPipeOutputStream() { @@ -401,43 +401,52 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) return result; #else // 1 - - HANDLE h_readPipe[2]; - HANDLE h_writePipe[2]; - HANDLE h_oldreadPipe; - HANDLE h_oldwritePipe; - BOOL inheritHandles; - - // ------------------------------------ - // Pipe handling - // We are in the case of opening a pipe - inheritHandles = FALSE; - if (handler && handler->NeedPipe()) { + + HANDLE hpipeRead[2]; + HANDLE hpipeWrite[2]; + HANDLE hStdIn = INVALID_HANDLE_VALUE; + HANDLE hStdOut = INVALID_HANDLE_VALUE; + + // we need to inherit handles in the child process if we want to redirect + // its IO + BOOL inheritHandles = FALSE; + + // open the pipes to which child process IO will be redirected if needed + if ( handler && handler->IsRedirected() ) + { SECURITY_ATTRIBUTES security; security.nLength = sizeof(security); security.lpSecurityDescriptor = NULL; security.bInheritHandle = TRUE; - if (! ::CreatePipe(&h_readPipe[0], &h_readPipe[1], &security, 0) ) { - wxLogSysError(_T("Can't create the inter-process read pipe")); + if ( !::CreatePipe(&hpipeRead[0], &hpipeRead[1], &security, 0) ) + { + wxLogSysError(_("Can't create the inter-process read pipe")); return 0; } - if (! ::CreatePipe(&h_writePipe[0], &h_writePipe[1], &security, 0) ) { - wxLogSysError(_T("Can't create the inter-process read pipe")); + if ( !::CreatePipe(&hpipeWrite[0], &hpipeWrite[1], &security, 0) ) + { + ::CloseHandle(hpipeRead[0]); + ::CloseHandle(hpipeRead[1]); + + wxLogSysError(_("Can't create the inter-process write pipe")); return 0; } // We need to save the old stdio handles to restore them after the call // to CreateProcess - h_oldreadPipe = GetStdHandle(STD_INPUT_HANDLE); - h_oldwritePipe = GetStdHandle(STD_OUTPUT_HANDLE); + hStdIn = ::GetStdHandle(STD_INPUT_HANDLE); + hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE); - SetStdHandle(STD_INPUT_HANDLE, h_readPipe[0]); - SetStdHandle(STD_OUTPUT_HANDLE, h_writePipe[1]); + if ( !::SetStdHandle(STD_INPUT_HANDLE, hpipeRead[0]) || + !::SetStdHandle(STD_OUTPUT_HANDLE, hpipeWrite[1]) ) + { + wxLogDebug(_T("Failed to change stdin/out handles")); + } inheritHandles = TRUE; } @@ -464,29 +473,37 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) &pi // process info ) == 0 ) { - if (inheritHandles) { - ::CloseHandle(h_writePipe[0]); - ::CloseHandle(h_writePipe[1]); - ::CloseHandle(h_readPipe[0]); - ::CloseHandle(h_readPipe[1]); + if ( inheritHandles ) + { + ::CloseHandle(hpipeWrite[0]); + ::CloseHandle(hpipeWrite[1]); + ::CloseHandle(hpipeRead[0]); + ::CloseHandle(hpipeRead[1]); } + wxLogSysError(_("Execution of command '%s' failed"), command.c_str()); return 0; } // Restore the old stdio handles - if (inheritHandles) { - SetStdHandle(STD_INPUT_HANDLE, h_oldreadPipe); - SetStdHandle(STD_OUTPUT_HANDLE, h_oldwritePipe); + if ( inheritHandles ) + { + if ( !::SetStdHandle(STD_INPUT_HANDLE, hStdIn) || + !::SetStdHandle(STD_OUTPUT_HANDLE, hStdOut) ) + { + wxLogDebug(_T("Failed to restore old stdin/out handles")); + } + + // they're still opened in child process + ::CloseHandle(hpipeWrite[1]); + ::CloseHandle(hpipeRead[0]); - ::CloseHandle(h_writePipe[1]); - ::CloseHandle(h_readPipe[0]); // We can now initialize the wxStreams - wxInputStream *processOutput = new wxPipeInputStream(h_writePipe[0]); - wxOutputStream *processInput = new wxPipeOutputStream(h_readPipe[1]); + wxInputStream *inStream = new wxPipeInputStream(hpipeWrite[0]); + wxOutputStream *outStream = new wxPipeOutputStream(hpipeRead[1]); - handler->SetPipeStreams(processOutput, processInput); + handler->SetPipeStreams(inStream, outStream); } // register the class for the hidden window used for the notifications @@ -522,8 +539,8 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) data->state = sync; if ( sync ) { - wxASSERT_MSG( !handler, wxT("wxProcess param ignored for sync execution") ); - + // handler may be !NULL for capturing program output, but we don't use + // it wxExecuteData struct in this case data->handler = NULL; } else @@ -589,16 +606,17 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) // waiting until command executed (disable everything while doing it) #if wxUSE_GUI - wxBeginBusyCursor(); - wxEnableTopLevelWindows(FALSE); + { + wxBusyCursor bc; + + wxWindowDisabler wd; #endif // wxUSE_GUI while ( data->state ) wxYield(); #if wxUSE_GUI - wxEnableTopLevelWindows(TRUE); - wxEndBusyCursor(); + } #endif // wxUSE_GUI DWORD dwExitCode = data->dwExitCode;