stdout redirection for Unix
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7490 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -78,11 +78,14 @@ public:
|
||||
#if wxUSE_STREAMS
|
||||
// Pipe handling
|
||||
wxInputStream *GetInputStream() const { return m_inputStream; }
|
||||
wxInputStream *GetErrorStream() const { return m_errorStream; }
|
||||
wxOutputStream *GetOutputStream() const { return m_outputStream; }
|
||||
|
||||
// implementation only (for wxExecute)
|
||||
void SetPipeStreams(wxInputStream *inStream, wxOutputStream *outStream);
|
||||
#endif
|
||||
void SetPipeStreams(wxInputStream *inStream,
|
||||
wxOutputStream *outStream,
|
||||
wxInputStream *errStream);
|
||||
#endif // wxUSE_STREAMS
|
||||
|
||||
protected:
|
||||
void Init(wxEvtHandler *parent, int id, bool redirect);
|
||||
@@ -90,9 +93,10 @@ protected:
|
||||
int m_id;
|
||||
|
||||
#if wxUSE_STREAMS
|
||||
wxInputStream *m_inputStream;
|
||||
wxInputStream *m_inputStream,
|
||||
*m_errorStream;
|
||||
wxOutputStream *m_outputStream;
|
||||
#endif
|
||||
#endif // wxUSE_STREAMS
|
||||
|
||||
bool m_redirect;
|
||||
};
|
||||
|
@@ -98,6 +98,10 @@ public:
|
||||
wxListBox *GetLogListBox() const { return m_lbox; }
|
||||
|
||||
private:
|
||||
void ShowOutput(const wxString& cmd,
|
||||
const wxArrayString& output,
|
||||
const wxString& title);
|
||||
|
||||
wxString m_cmdLast;
|
||||
|
||||
wxListBox *m_lbox;
|
||||
@@ -381,23 +385,15 @@ void MyFrame::OnExecWithRedirect(wxCommandEvent& WXUNUSED(event))
|
||||
|
||||
if ( sync )
|
||||
{
|
||||
wxArrayString output;
|
||||
wxArrayString output, errors;
|
||||
int code = wxExecute(cmd, output);
|
||||
wxLogStatus(_T("command '%s' terminated with exit code %d."),
|
||||
cmd.c_str(), code);
|
||||
|
||||
if ( code != -1 )
|
||||
{
|
||||
m_lbox->Append(wxString::Format(_T("--- Output of '%s' ---"),
|
||||
cmd.c_str()));
|
||||
|
||||
size_t count = output.GetCount();
|
||||
for ( size_t n = 0; n < count; n++ )
|
||||
{
|
||||
m_lbox->Append(output[n]);
|
||||
}
|
||||
|
||||
m_lbox->Append(_T("--- End of output ---"));
|
||||
ShowOutput(cmd, output, _T("Output"));
|
||||
ShowOutput(cmd, errors, _T("Errors"));
|
||||
}
|
||||
}
|
||||
else // async exec
|
||||
@@ -478,6 +474,26 @@ void MyFrame::OnProcessTerminated(MyPipedProcess *process)
|
||||
m_running.Remove(process);
|
||||
}
|
||||
|
||||
|
||||
void MyFrame::ShowOutput(const wxString& cmd,
|
||||
const wxArrayString& output,
|
||||
const wxString& title)
|
||||
{
|
||||
size_t count = output.GetCount();
|
||||
if ( !count )
|
||||
return;
|
||||
|
||||
m_lbox->Append(wxString::Format(_T("--- %s of '%s' ---"),
|
||||
title.c_str(), cmd.c_str()));
|
||||
|
||||
for ( size_t n = 0; n < count; n++ )
|
||||
{
|
||||
m_lbox->Append(output[n]);
|
||||
}
|
||||
|
||||
m_lbox->Append(_T("--- End of output ---"));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MyProcess
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -497,6 +513,8 @@ void MyProcess::OnTerminate(int pid, int status)
|
||||
|
||||
bool MyPipedProcess::HasInput()
|
||||
{
|
||||
bool hasInput = FALSE;
|
||||
|
||||
wxInputStream& is = *GetInputStream();
|
||||
if ( !is.Eof() )
|
||||
{
|
||||
@@ -504,16 +522,28 @@ bool MyPipedProcess::HasInput()
|
||||
|
||||
// this assumes that the output is always line buffered
|
||||
wxString msg;
|
||||
msg << m_cmd << _T(": ") << tis.ReadLine();
|
||||
msg << m_cmd << _T(" (stdout): ") << tis.ReadLine();
|
||||
|
||||
m_parent->GetLogListBox()->Append(msg);
|
||||
|
||||
return TRUE;
|
||||
hasInput = TRUE;
|
||||
}
|
||||
else
|
||||
|
||||
wxInputStream& es = *GetErrorStream();
|
||||
if ( !es.Eof() )
|
||||
{
|
||||
return FALSE;
|
||||
wxTextInputStream tis(es);
|
||||
|
||||
// this assumes that the output is always line buffered
|
||||
wxString msg;
|
||||
msg << m_cmd << _T(" (stderr): ") << tis.ReadLine();
|
||||
|
||||
m_parent->GetLogListBox()->Append(msg);
|
||||
|
||||
hasInput = TRUE;
|
||||
}
|
||||
|
||||
return hasInput;
|
||||
}
|
||||
|
||||
void MyPipedProcess::OnTerminate(int pid, int status)
|
||||
|
@@ -39,16 +39,18 @@ void wxProcess::Init(wxEvtHandler *parent, int id, bool redirect)
|
||||
|
||||
#if wxUSE_STREAMS
|
||||
m_inputStream = NULL;
|
||||
m_errorStream = NULL;
|
||||
m_outputStream = NULL;
|
||||
#endif
|
||||
#endif // wxUSE_STREAMS
|
||||
}
|
||||
|
||||
wxProcess::~wxProcess()
|
||||
{
|
||||
#if wxUSE_STREAMS
|
||||
delete m_inputStream;
|
||||
delete m_errorStream;
|
||||
delete m_outputStream;
|
||||
#endif
|
||||
#endif // wxUSE_STREAMS
|
||||
}
|
||||
|
||||
void wxProcess::OnTerminate(int pid, int status)
|
||||
@@ -67,9 +69,14 @@ void wxProcess::Detach()
|
||||
}
|
||||
|
||||
#if wxUSE_STREAMS
|
||||
void wxProcess::SetPipeStreams(wxInputStream *in_stream, wxOutputStream *out_stream)
|
||||
|
||||
void wxProcess::SetPipeStreams(wxInputStream *inputSstream,
|
||||
wxOutputStream *outputStream,
|
||||
wxInputStream *errorStream)
|
||||
{
|
||||
m_inputStream = in_stream;
|
||||
m_outputStream = out_stream;
|
||||
m_inputStream = inputSstream;
|
||||
m_errorStream = errorStream;
|
||||
m_outputStream = outputStream;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // wxUSE_STREAMS
|
||||
|
@@ -498,7 +498,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
wxInputStream *inStream = new wxPipeInputStream(hpipeStdout[0]);
|
||||
wxOutputStream *outStream = new wxPipeOutputStream(hpipeStdin[1]);
|
||||
|
||||
handler->SetPipeStreams(inStream, outStream);
|
||||
handler->SetPipeStreams(inStream, outStream, NULL);
|
||||
}
|
||||
#endif // wxUSE_STREAMS
|
||||
|
||||
|
@@ -436,14 +436,18 @@ long wxExecute(wxChar **argv,
|
||||
}
|
||||
#endif // wxUSE_GUI
|
||||
|
||||
int pipeIn[2];
|
||||
int pipeOut[2];
|
||||
// pipes for inter process communication
|
||||
int pipeIn[2], // stdin
|
||||
pipeOut[2], // stdout
|
||||
pipeErr[2]; // stderr
|
||||
|
||||
pipeIn[0] = pipeIn[1] =
|
||||
pipeOut[0] = pipeOut[1] = -1;
|
||||
pipeOut[0] = pipeOut[1] =
|
||||
pipeErr[0] = pipeErr[1] = -1;
|
||||
|
||||
if ( process && process->IsRedirected() )
|
||||
{
|
||||
if ( pipe(pipeIn) == -1 || pipe(pipeOut) == -1 )
|
||||
if ( pipe(pipeIn) == -1 || pipe(pipeOut) == -1 || pipe(pipeErr) == -1 )
|
||||
{
|
||||
#if wxUSE_GUI
|
||||
// free previously allocated resources
|
||||
@@ -476,6 +480,8 @@ long wxExecute(wxChar **argv,
|
||||
close(pipeIn[1]);
|
||||
close(pipeOut[0]);
|
||||
close(pipeOut[1]);
|
||||
close(pipeErr[0]);
|
||||
close(pipeErr[1]);
|
||||
#endif // wxUSE_GUI
|
||||
|
||||
wxLogSysError( _("Fork failed") );
|
||||
@@ -498,7 +504,7 @@ long wxExecute(wxChar **argv,
|
||||
{
|
||||
for ( int fd = 0; fd < FD_SETSIZE; fd++ )
|
||||
{
|
||||
if ( fd == pipeIn[0] || fd == pipeOut[1]
|
||||
if ( fd == pipeIn[0] || fd == pipeOut[1] || fd == pipeErr[1]
|
||||
#if wxUSE_GUI
|
||||
|| fd == end_proc_detect[1]
|
||||
#endif // wxUSE_GUI
|
||||
@@ -514,19 +520,19 @@ long wxExecute(wxChar **argv,
|
||||
}
|
||||
}
|
||||
|
||||
// redirect stdio and stdout
|
||||
// (TODO: what about stderr?)
|
||||
// redirect stdio, stdout and stderr
|
||||
if ( pipeIn[0] != -1 )
|
||||
{
|
||||
if ( dup2(pipeIn[0], STDIN_FILENO) == -1 ||
|
||||
dup2(pipeOut[1], STDOUT_FILENO) == -1 )
|
||||
dup2(pipeOut[1], STDOUT_FILENO) == -1 ||
|
||||
dup2(pipeErr[1], STDERR_FILENO) == -1 )
|
||||
{
|
||||
wxLogSysError(_("Failed to redirect child process "
|
||||
"input/output"));
|
||||
wxLogSysError(_("Failed to redirect child process input/output"));
|
||||
}
|
||||
|
||||
close(pipeIn[0]);
|
||||
close(pipeOut[1]);
|
||||
close(pipeErr[1]);
|
||||
}
|
||||
|
||||
execvp (*mb_argv, mb_argv);
|
||||
@@ -544,10 +550,13 @@ long wxExecute(wxChar **argv,
|
||||
// These two streams are relative to this process.
|
||||
wxOutputStream *outStream = new wxProcessFileOutputStream(pipeIn[1]);
|
||||
wxInputStream *inStream = new wxProcessFileInputStream(pipeOut[0]);
|
||||
wxInputStream *errStream = new wxProcessFileInputStream(pipeErr[0]);
|
||||
|
||||
close(pipeIn[0]); // close reading side
|
||||
close(pipeOut[1]); // close writing side
|
||||
close(pipeErr[1]); // close writing side
|
||||
|
||||
process->SetPipeStreams(inStream, outStream);
|
||||
process->SetPipeStreams(inStream, outStream, errStream);
|
||||
}
|
||||
|
||||
#if wxUSE_GUI
|
||||
|
Reference in New Issue
Block a user