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:
Vadim Zeitlin
2000-05-25 18:35:52 +00:00
parent b912a066c2
commit 54d5ffd6c3
5 changed files with 87 additions and 37 deletions

View File

@@ -78,11 +78,14 @@ public:
#if wxUSE_STREAMS #if wxUSE_STREAMS
// Pipe handling // Pipe handling
wxInputStream *GetInputStream() const { return m_inputStream; } wxInputStream *GetInputStream() const { return m_inputStream; }
wxInputStream *GetErrorStream() const { return m_errorStream; }
wxOutputStream *GetOutputStream() const { return m_outputStream; } wxOutputStream *GetOutputStream() const { return m_outputStream; }
// implementation only (for wxExecute) // implementation only (for wxExecute)
void SetPipeStreams(wxInputStream *inStream, wxOutputStream *outStream); void SetPipeStreams(wxInputStream *inStream,
#endif wxOutputStream *outStream,
wxInputStream *errStream);
#endif // wxUSE_STREAMS
protected: protected:
void Init(wxEvtHandler *parent, int id, bool redirect); void Init(wxEvtHandler *parent, int id, bool redirect);
@@ -90,9 +93,10 @@ protected:
int m_id; int m_id;
#if wxUSE_STREAMS #if wxUSE_STREAMS
wxInputStream *m_inputStream; wxInputStream *m_inputStream,
*m_errorStream;
wxOutputStream *m_outputStream; wxOutputStream *m_outputStream;
#endif #endif // wxUSE_STREAMS
bool m_redirect; bool m_redirect;
}; };

View File

@@ -98,6 +98,10 @@ public:
wxListBox *GetLogListBox() const { return m_lbox; } wxListBox *GetLogListBox() const { return m_lbox; }
private: private:
void ShowOutput(const wxString& cmd,
const wxArrayString& output,
const wxString& title);
wxString m_cmdLast; wxString m_cmdLast;
wxListBox *m_lbox; wxListBox *m_lbox;
@@ -381,23 +385,15 @@ void MyFrame::OnExecWithRedirect(wxCommandEvent& WXUNUSED(event))
if ( sync ) if ( sync )
{ {
wxArrayString output; wxArrayString output, errors;
int code = wxExecute(cmd, output); int code = wxExecute(cmd, output);
wxLogStatus(_T("command '%s' terminated with exit code %d."), wxLogStatus(_T("command '%s' terminated with exit code %d."),
cmd.c_str(), code); cmd.c_str(), code);
if ( code != -1 ) if ( code != -1 )
{ {
m_lbox->Append(wxString::Format(_T("--- Output of '%s' ---"), ShowOutput(cmd, output, _T("Output"));
cmd.c_str())); ShowOutput(cmd, errors, _T("Errors"));
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 ---"));
} }
} }
else // async exec else // async exec
@@ -478,6 +474,26 @@ void MyFrame::OnProcessTerminated(MyPipedProcess *process)
m_running.Remove(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 // MyProcess
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -497,6 +513,8 @@ void MyProcess::OnTerminate(int pid, int status)
bool MyPipedProcess::HasInput() bool MyPipedProcess::HasInput()
{ {
bool hasInput = FALSE;
wxInputStream& is = *GetInputStream(); wxInputStream& is = *GetInputStream();
if ( !is.Eof() ) if ( !is.Eof() )
{ {
@@ -504,16 +522,28 @@ bool MyPipedProcess::HasInput()
// this assumes that the output is always line buffered // this assumes that the output is always line buffered
wxString msg; wxString msg;
msg << m_cmd << _T(": ") << tis.ReadLine(); msg << m_cmd << _T(" (stdout): ") << tis.ReadLine();
m_parent->GetLogListBox()->Append(msg); 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) void MyPipedProcess::OnTerminate(int pid, int status)

View File

@@ -39,16 +39,18 @@ void wxProcess::Init(wxEvtHandler *parent, int id, bool redirect)
#if wxUSE_STREAMS #if wxUSE_STREAMS
m_inputStream = NULL; m_inputStream = NULL;
m_errorStream = NULL;
m_outputStream = NULL; m_outputStream = NULL;
#endif #endif // wxUSE_STREAMS
} }
wxProcess::~wxProcess() wxProcess::~wxProcess()
{ {
#if wxUSE_STREAMS #if wxUSE_STREAMS
delete m_inputStream; delete m_inputStream;
delete m_errorStream;
delete m_outputStream; delete m_outputStream;
#endif #endif // wxUSE_STREAMS
} }
void wxProcess::OnTerminate(int pid, int status) void wxProcess::OnTerminate(int pid, int status)
@@ -67,9 +69,14 @@ void wxProcess::Detach()
} }
#if wxUSE_STREAMS #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_inputStream = inputSstream;
m_outputStream = out_stream; m_errorStream = errorStream;
m_outputStream = outputStream;
} }
#endif
#endif // wxUSE_STREAMS

View File

@@ -498,7 +498,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
wxInputStream *inStream = new wxPipeInputStream(hpipeStdout[0]); wxInputStream *inStream = new wxPipeInputStream(hpipeStdout[0]);
wxOutputStream *outStream = new wxPipeOutputStream(hpipeStdin[1]); wxOutputStream *outStream = new wxPipeOutputStream(hpipeStdin[1]);
handler->SetPipeStreams(inStream, outStream); handler->SetPipeStreams(inStream, outStream, NULL);
} }
#endif // wxUSE_STREAMS #endif // wxUSE_STREAMS

View File

@@ -436,14 +436,18 @@ long wxExecute(wxChar **argv,
} }
#endif // wxUSE_GUI #endif // wxUSE_GUI
int pipeIn[2]; // pipes for inter process communication
int pipeOut[2]; int pipeIn[2], // stdin
pipeOut[2], // stdout
pipeErr[2]; // stderr
pipeIn[0] = pipeIn[1] = pipeIn[0] = pipeIn[1] =
pipeOut[0] = pipeOut[1] = -1; pipeOut[0] = pipeOut[1] =
pipeErr[0] = pipeErr[1] = -1;
if ( process && process->IsRedirected() ) if ( process && process->IsRedirected() )
{ {
if ( pipe(pipeIn) == -1 || pipe(pipeOut) == -1 ) if ( pipe(pipeIn) == -1 || pipe(pipeOut) == -1 || pipe(pipeErr) == -1 )
{ {
#if wxUSE_GUI #if wxUSE_GUI
// free previously allocated resources // free previously allocated resources
@@ -476,6 +480,8 @@ long wxExecute(wxChar **argv,
close(pipeIn[1]); close(pipeIn[1]);
close(pipeOut[0]); close(pipeOut[0]);
close(pipeOut[1]); close(pipeOut[1]);
close(pipeErr[0]);
close(pipeErr[1]);
#endif // wxUSE_GUI #endif // wxUSE_GUI
wxLogSysError( _("Fork failed") ); wxLogSysError( _("Fork failed") );
@@ -498,7 +504,7 @@ long wxExecute(wxChar **argv,
{ {
for ( int fd = 0; fd < FD_SETSIZE; fd++ ) 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 #if wxUSE_GUI
|| fd == end_proc_detect[1] || fd == end_proc_detect[1]
#endif // wxUSE_GUI #endif // wxUSE_GUI
@@ -514,19 +520,19 @@ long wxExecute(wxChar **argv,
} }
} }
// redirect stdio and stdout // redirect stdio, stdout and stderr
// (TODO: what about stderr?)
if ( pipeIn[0] != -1 ) if ( pipeIn[0] != -1 )
{ {
if ( dup2(pipeIn[0], STDIN_FILENO) == -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 " wxLogSysError(_("Failed to redirect child process input/output"));
"input/output"));
} }
close(pipeIn[0]); close(pipeIn[0]);
close(pipeOut[1]); close(pipeOut[1]);
close(pipeErr[1]);
} }
execvp (*mb_argv, mb_argv); execvp (*mb_argv, mb_argv);
@@ -544,10 +550,13 @@ long wxExecute(wxChar **argv,
// These two streams are relative to this process. // These two streams are relative to this process.
wxOutputStream *outStream = new wxProcessFileOutputStream(pipeIn[1]); wxOutputStream *outStream = new wxProcessFileOutputStream(pipeIn[1]);
wxInputStream *inStream = new wxProcessFileInputStream(pipeOut[0]); wxInputStream *inStream = new wxProcessFileInputStream(pipeOut[0]);
wxInputStream *errStream = new wxProcessFileInputStream(pipeErr[0]);
close(pipeIn[0]); // close reading side close(pipeIn[0]); // close reading side
close(pipeOut[1]); // close writing 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 #if wxUSE_GUI