Code::Blocks  SVN r11506
cbexecute.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3  * http://www.gnu.org/licenses/lgpl-3.0.html
4  */
5 
6 /*
7  * inline long cbSyncExecute(const wxString& command, wxArrayString& output, wxArrayString& error)
8  * inline long cbSyncExecute(const wxString& command, wxArrayString& output)
9  *
10  * Implements behaviour identical to synchronous wxExecute, but uses *safe* yields
11  * and is aware of application shutdowns (will stop polling and send SIGTERM to other process).
12  *
13  * Can be used in place of wxExecute to avoid possible wxYield() reentrancy problems (code completion and tool manager?)
14  */
15 
16 #ifndef CBEXECUTE
17 #define CBEXECUTE
18 
19 #include "manager.h"
20 
22 {
25 
28  bool running;
29  int exitCode;
30 
31 public:
32  cbExecuteProcess(wxArrayString* out, wxArrayString* err) : std_out(out), std_err(err), running(true)
33  {
34  Redirect();
35  };
36 
37  void FlushPipe()
38  {
39  wxString line;
40  stream_stdout = GetInputStream();
41  stream_stderr = GetErrorStream();
42 
43  if (stream_stdout && stream_stderr)
44  {
45  wxTextInputStream t_stream_stdout(*stream_stdout);
46  wxTextInputStream t_stream_stderr(*stream_stderr);
47 
48  while (! stream_stdout->Eof() )
49  {
50  line = t_stream_stdout.ReadLine();
51  std_out->Add(line);
52  }
53 
54  if (std_err)
55  {
56  while (! stream_stderr->Eof() )
57  {
58  line = t_stream_stderr.ReadLine();
59  std_err->Add(line);
60  }
61  }
62  }
63  };
64 
65  virtual void OnTerminate(int pid, int status)
66  {
67  FlushPipe();
68  exitCode = status;
69  running = false;
70  }
71 
72  bool Running()
73  {
74  return running;
75  };
76  bool ExitCode()
77  {
78  return exitCode;
79  };
80 
81 };
82 
83 inline long cbSyncExecute(const wxString& command, wxArrayString& output, wxArrayString& error)
84 {
85  cbExecuteProcess process(&output, &error);
86 
87  if (wxExecute(command, wxEXEC_ASYNC, &process) == 0)
88  return -1;
89 
90  while (process.Running())
91  {
93  {
94  process.Kill(wxSIGTERM); // will not work under Windows
95  return -1;
96  }
98  }
99  return process.ExitCode();
100 }
101 
102 inline long cbSyncExecute(const wxString& command, wxArrayString& output)
103 {
104  cbExecuteProcess process(&output, 0);
105 
106  if (wxExecute(command, wxEXEC_ASYNC, &process) == 0)
107  return -1;
108 
109  while (process.Running())
110  {
112  {
113  process.Kill(wxSIGTERM);
114  return -1;
115  }
116  Manager::Yield();
117  }
118  return process.ExitCode();
119 }
120 
121 #endif
virtual void OnTerminate(int pid, int status)
Definition: cbexecute.h:65
void Redirect()
wxInputStream * GetInputStream() const
static bool IsAppShuttingDown()
Definition: manager.cpp:333
long cbSyncExecute(const wxString &command, wxArrayString &output, wxArrayString &error)
Definition: cbexecute.h:83
wxArrayString * std_out
Definition: cbexecute.h:26
wxString ReadLine()
void FlushPipe()
Definition: cbexecute.h:37
wxInputStream * GetErrorStream() const
wxInputStream * stream_stdout
Definition: cbexecute.h:23
static void Yield()
Whenever you need to call wxYield(), call Manager::Yield(). It's safer.
Definition: manager.cpp:221
wxArrayString * std_err
Definition: cbexecute.h:27
wxInputStream * stream_stderr
Definition: cbexecute.h:24
bool Running()
Definition: cbexecute.h:72
size_t Add(const wxString &str, size_t copies=1)
bool ExitCode()
Definition: cbexecute.h:76
cbExecuteProcess(wxArrayString *out, wxArrayString *err)
Definition: cbexecute.h:32
static wxKillError Kill(int pid, wxSignal sig=wxSIGTERM, int flags=wxKILL_NOCHILDREN)
long wxExecute(const wxString &command, int flags=wxEXEC_ASYNC, wxProcess *callback=NULL, const wxExecuteEnv *env=NULL)