]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/exec/exec.cpp
Applied patch [ 598173 ] Fixes erroneous logging notebook sample
[wxWidgets.git] / samples / exec / exec.cpp
index 7791cc180139094c30a0bdec37d402b359cea847..6c66fce22121064afc7b837a518930d7844cfb8b 100644 (file)
@@ -122,7 +122,7 @@ private:
     void DoAsyncExec(const wxString& cmd);
 
     // the PID of the last process we launched asynchronously
-    int m_pidLast;
+    long m_pidLast;
 
     // last command we executed
     wxString m_cmdLast;
@@ -165,7 +165,16 @@ protected:
 
     void OnClose(wxCloseEvent& event);
 
-    void DoSend() { m_out.WriteString(m_textIn->GetValue() + '\n'); DoGet(); }
+    void OnProcessTerm(wxProcessEvent& event);
+
+    void DoSend()
+    {
+        m_out.WriteString(m_textIn->GetValue() + '\n');
+        m_textIn->Clear();
+
+        DoGet();
+    }
+
     void DoGet();
 
 private:
@@ -303,6 +312,8 @@ BEGIN_EVENT_TABLE(MyPipeFrame, wxFrame)
     EVT_TEXT_ENTER(-1, MyPipeFrame::OnTextEnter)
 
     EVT_CLOSE(MyPipeFrame::OnClose)
+
+    EVT_END_PROCESS(-1, MyPipeFrame::OnProcessTerm)
 END_EVENT_TABLE()
 
 // Create a new application object: this macro will allow wxWindows to create
@@ -505,16 +516,16 @@ void MyFrame::OnKill(wxCommandEvent& WXUNUSED(event))
     if ( sig == 0 )
     {
         if ( wxProcess::Exists(pid) )
-            wxLogStatus(_T("Process %d is running."), pid);
+            wxLogStatus(_T("Process %ld is running."), pid);
         else
-            wxLogStatus(_T("No process with pid = %d."), pid);
+            wxLogStatus(_T("No process with pid = %ld."), pid);
     }
     else // not SIGNONE
     {
         wxKillError rc = wxProcess::Kill(pid, (wxSignal)sig);
         if ( rc == wxKILL_OK )
         {
-            wxLogStatus(_T("Process %d killed with signal %d."), pid, sig);
+            wxLogStatus(_T("Process %ld killed with signal %d."), pid, sig);
         }
         else
         {
@@ -527,7 +538,7 @@ void MyFrame::OnKill(wxCommandEvent& WXUNUSED(event))
                 _T("unspecified error"),
             };
 
-            wxLogStatus(_T("Failed to kill process %d with signal %d: %s"),
+            wxLogStatus(_T("Failed to kill process %ld with signal %d: %s"),
                         pid, sig, errorText[rc]);
         }
     }
@@ -543,13 +554,14 @@ void MyFrame::DoAsyncExec(const wxString& cmd)
     m_pidLast = wxExecute(cmd, wxEXEC_ASYNC, process);
     if ( !m_pidLast )
     {
-        wxLogError(_T("Execution of '%s' failed."), cmd.c_str());
+        wxLogError( _T("Execution of '%s' failed."), cmd.c_str() );
 
         delete process;
     }
     else
     {
-        wxLogStatus(_T("Process %ld (%s) launched."), m_pidLast, cmd.c_str());
+        wxLogStatus( _T("Process %ld (%s) launched."),
+            m_pidLast, cmd.c_str() );
 
         m_cmdLast = cmd;
     }
@@ -564,12 +576,13 @@ void MyFrame::OnSyncExec(wxCommandEvent& WXUNUSED(event))
     if ( !cmd )
         return;
 
-    wxLogStatus(_T("'%s' is running please wait..."), cmd.c_str());
+    wxLogStatus( _T("'%s' is running please wait..."), cmd.c_str() );
 
     int code = wxExecute(cmd, wxEXEC_SYNC);
 
     wxLogStatus(_T("Process '%s' terminated with exit code %d."),
-                cmd.c_str(), code);
+        cmd.c_str(), code);
+
     m_cmdLast = cmd;
 }
 
@@ -676,10 +689,10 @@ void MyFrame::OnExecWithPipe(wxCommandEvent& WXUNUSED(event))
 
     // always execute the filter asynchronously
     MyPipedProcess2 *process = new MyPipedProcess2(this, cmd, input);
-    int pid = wxExecute(cmd, wxEXEC_ASYNC, process);
+    long pid = wxExecute(cmd, wxEXEC_ASYNC, process);
     if ( pid )
     {
-        wxLogStatus(_T("Process %ld (%s) launched."), pid, cmd.c_str());
+        wxLogStatus( _T("Process %ld (%s) launched."), pid, cmd.c_str() );
 
         m_running.Add(process);
     }
@@ -982,25 +995,29 @@ MyPipeFrame::MyPipeFrame(wxFrame *parent,
              m_in(*process->GetInputStream()),
              m_out(*process->GetOutputStream())
 {
-    m_textIn = new wxTextCtrl(this, -1, _T(""),
+    m_process->SetNextHandler(this);
+
+    wxPanel *panel = new wxPanel(this, -1);
+
+    m_textIn = new wxTextCtrl(panel, -1, _T(""),
                               wxDefaultPosition, wxDefaultSize,
                               wxTE_PROCESS_ENTER);
-    m_textOut = new wxTextCtrl(this, -1, _T(""));
+    m_textOut = new wxTextCtrl(panel, -1, _T(""));
     m_textOut->SetEditable(FALSE);
 
     wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
     sizerTop->Add(m_textIn, 0, wxGROW | wxALL, 5);
 
     wxSizer *sizerBtns = new wxBoxSizer(wxHORIZONTAL);
-    sizerBtns->Add(new wxButton(this, Exec_Btn_Send, _T("&Send")), 0,
+    sizerBtns->Add(new wxButton(panel, Exec_Btn_Send, _T("&Send")), 0,
                    wxALL, 10);
-    sizerBtns->Add(new wxButton(this, Exec_Btn_Get, _T("&Get")), 0,
+    sizerBtns->Add(new wxButton(panel, Exec_Btn_Get, _T("&Get")), 0,
                    wxALL, 10);
 
     sizerTop->Add(sizerBtns, 0, wxCENTRE | wxALL, 5);
     sizerTop->Add(m_textOut, 0, wxGROW | wxALL, 5);
 
-    SetSizer(sizerTop);
+    panel->SetSizer(sizerTop);
     sizerTop->Fit(this);
 
     Show();
@@ -1008,13 +1025,40 @@ MyPipeFrame::MyPipeFrame(wxFrame *parent,
 
 void MyPipeFrame::DoGet()
 {
+    // we don't have any way to be notified when any input appears on the
+    // stream so we have to poll it :-(
+    //
+    // NB: this really must be done because otherwise the other program might
+    //     not have enough time to receive or process our data and we'd read
+    //     an empty string
+    while ( !m_process->IsInputAvailable() && m_process->IsInputOpened() )
+        ;
+
     m_textOut->SetValue(m_in.ReadLine());
 }
 
 void MyPipeFrame::OnClose(wxCloseEvent& event)
 {
-    m_process->CloseOutput();
+    if ( m_process )
+    {
+        // we're not interested in getting the process termination notification
+        // if we are closing it ourselves
+        wxProcess *process = m_process;
+        m_process = NULL;
+        process->SetNextHandler(NULL);
+
+        process->CloseOutput();
+    }
 
     event.Skip();
 }
 
+void MyPipeFrame::OnProcessTerm(wxProcessEvent& event)
+{
+    delete m_process;
+    m_process = NULL;
+
+    wxLogWarning(_T("The other process has terminated, closing"));
+
+    Close();
+}