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