1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: wx/process.h 3 // Purpose: wxProcess class 4 // Author: Guilhem Lavaux 5 // Modified by: Vadim Zeitlin to check error codes, added Detach() method 6 // Created: 24/06/98 7 // Copyright: (c) 1998 Guilhem Lavaux 8 // Licence: wxWindows licence 9 ///////////////////////////////////////////////////////////////////////////// 10 11 #ifndef _WX_PROCESSH__ 12 #define _WX_PROCESSH__ 13 14 #include "wx/event.h" 15 16 #if wxUSE_STREAMS 17 #include "wx/stream.h" 18 #endif 19 20 #include "wx/utils.h" // for wxSignal 21 22 // the wxProcess creation flags 23 enum 24 { 25 // no redirection 26 wxPROCESS_DEFAULT = 0, 27 28 // redirect the IO of the child process 29 wxPROCESS_REDIRECT = 1 30 }; 31 32 // ---------------------------------------------------------------------------- 33 // A wxProcess object should be passed to wxExecute - than its OnTerminate() 34 // function will be called when the process terminates. 35 // ---------------------------------------------------------------------------- 36 37 class WXDLLIMPEXP_BASE wxProcess : public wxEvtHandler 38 { 39 public: 40 // kill the process with the given PID 41 static wxKillError Kill(int pid, wxSignal sig = wxSIGTERM, int flags = wxKILL_NOCHILDREN); 42 43 // test if the given process exists 44 static bool Exists(int pid); 45 46 // this function replaces the standard popen() one: it launches a process 47 // asynchronously and allows the caller to get the streams connected to its 48 // std{in|out|err} 49 // 50 // on error NULL is returned, in any case the process object will be 51 // deleted automatically when the process terminates and should *not* be 52 // deleted by the caller 53 static wxProcess *Open(const wxString& cmd, int flags = wxEXEC_ASYNC); 54 55 56 // ctors 57 wxProcess(wxEvtHandler *parent = NULL, int nId = wxID_ANY) 58 { Init(parent, nId, wxPROCESS_DEFAULT); } 59 wxProcess(int flags)60 wxProcess(int flags) { Init(NULL, wxID_ANY, flags); } 61 62 virtual ~wxProcess(); 63 64 // get the process ID of the process executed by Open() GetPid()65 long GetPid() const { return m_pid; } 66 67 // may be overridden to be notified about process termination 68 virtual void OnTerminate(int pid, int status); 69 70 // call this before passing the object to wxExecute() to redirect the 71 // launched process stdin/stdout, then use GetInputStream() and 72 // GetOutputStream() to get access to them Redirect()73 void Redirect() { m_redirect = true; } IsRedirected()74 bool IsRedirected() const { return m_redirect; } 75 76 // detach from the parent - should be called by the parent if it's deleted 77 // before the process it started terminates 78 void Detach(); 79 80 #if wxUSE_STREAMS 81 // Pipe handling GetInputStream()82 wxInputStream *GetInputStream() const { return m_inputStream; } GetErrorStream()83 wxInputStream *GetErrorStream() const { return m_errorStream; } GetOutputStream()84 wxOutputStream *GetOutputStream() const { return m_outputStream; } 85 86 // close the output stream indicating that nothing more will be written CloseOutput()87 void CloseOutput() { delete m_outputStream; m_outputStream = NULL; } 88 89 // return true if the child process stdout is not closed 90 bool IsInputOpened() const; 91 92 // return true if any input is available on the child process stdout/err 93 bool IsInputAvailable() const; 94 bool IsErrorAvailable() const; 95 96 // implementation only (for wxExecute) 97 // 98 // NB: the streams passed here should correspond to the child process 99 // stdout, stdin and stderr and here the normal naming convention is 100 // used unlike elsewhere in this class 101 void SetPipeStreams(wxInputStream *outStream, 102 wxOutputStream *inStream, 103 wxInputStream *errStream); 104 #endif // wxUSE_STREAMS 105 106 // priority 107 // Sets the priority to the given value: see wxPRIORITY_XXX constants. 108 // 109 // NB: the priority can only be set before the process is created 110 void SetPriority(unsigned priority); 111 112 // Get the current priority. GetPriority()113 unsigned GetPriority() const { return m_priority; } 114 115 // implementation only - don't use! 116 // -------------------------------- 117 118 // needs to be public since it needs to be used from wxExecute() global func SetPid(long pid)119 void SetPid(long pid) { m_pid = pid; } 120 121 protected: 122 void Init(wxEvtHandler *parent, int id, int flags); 123 124 int m_id; 125 long m_pid; 126 127 unsigned m_priority; 128 129 #if wxUSE_STREAMS 130 // these streams are connected to stdout, stderr and stdin of the child 131 // process respectively (yes, m_inputStream corresponds to stdout -- very 132 // confusing but too late to change now) 133 wxInputStream *m_inputStream, 134 *m_errorStream; 135 wxOutputStream *m_outputStream; 136 #endif // wxUSE_STREAMS 137 138 bool m_redirect; 139 140 DECLARE_DYNAMIC_CLASS(wxProcess) 141 wxDECLARE_NO_COPY_CLASS(wxProcess); 142 }; 143 144 // ---------------------------------------------------------------------------- 145 // wxProcess events 146 // ---------------------------------------------------------------------------- 147 148 class WXDLLIMPEXP_FWD_BASE wxProcessEvent; 149 150 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_BASE, wxEVT_END_PROCESS, wxProcessEvent ); 151 152 class WXDLLIMPEXP_BASE wxProcessEvent : public wxEvent 153 { 154 public: wxEvent(nId)155 wxProcessEvent(int nId = 0, int pid = 0, int exitcode = 0) : wxEvent(nId) 156 { 157 m_eventType = wxEVT_END_PROCESS; 158 m_pid = pid; 159 m_exitcode = exitcode; 160 } 161 162 // accessors 163 // PID of process which terminated GetPid()164 int GetPid() { return m_pid; } 165 166 // the exit code GetExitCode()167 int GetExitCode() { return m_exitcode; } 168 169 // implement the base class pure virtual Clone()170 virtual wxEvent *Clone() const { return new wxProcessEvent(*this); } 171 172 public: 173 int m_pid, 174 m_exitcode; 175 176 DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxProcessEvent) 177 }; 178 179 typedef void (wxEvtHandler::*wxProcessEventFunction)(wxProcessEvent&); 180 181 #define wxProcessEventHandler(func) \ 182 wxEVENT_HANDLER_CAST(wxProcessEventFunction, func) 183 184 #define EVT_END_PROCESS(id, func) \ 185 wx__DECLARE_EVT1(wxEVT_END_PROCESS, id, wxProcessEventHandler(func)) 186 187 #endif // _WX_PROCESSH__ 188