From da00a8bb164dd1f58dd0bb211475538a375867b4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 12 Jul 2002 18:15:49 +0000 Subject: [PATCH] added and documented wxProcess::Open() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16152 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/process.tex | 37 ++++++++++++++++++++++++++ include/wx/process.h | 56 +++++++++++++++++++++++++++++++-------- src/common/process.cpp | 18 +++++++++++-- 3 files changed, 98 insertions(+), 13 deletions(-) diff --git a/docs/latex/wx/process.tex b/docs/latex/wx/process.tex index f8475c9e63..98e90695dc 100644 --- a/docs/latex/wx/process.tex +++ b/docs/latex/wx/process.tex @@ -45,6 +45,8 @@ for explicit destruction.} \func{}{wxProcess}{\param{wxEvtHandler *}{ parent = NULL}, \param{int}{ id = -1}} +\func{}{wxProcess}{\param{int }{flags}} + Constructs a process object. {\it id} is only used in the case you want to use wxWindows events. It identifies this object, or another window that will receive the event. @@ -53,12 +55,20 @@ If the {\it parent} parameter is different from NULL, it will receive a wxEVT\_END\_PROCESS notification event (you should insert EVT\_END\_PROCESS macro in the event table of the parent to handle it) with the given {\it id}. +The second constructor creates an object without any associated parent (and +hence no id neither) but allows to specify the {\it flags} which can have the +value of {\tt wxPROCESS\_DEFAULT} or {\tt wxPROCESS\_REDIRECT}. Specifying the +former value has no particular effect while using the latter one is equivalent +to calling \helpref{Redirect}{wxprocessredirect}. + \wxheading{Parameters} \docparam{parent}{The event handler parent.} \docparam{id}{id of an event.} +\docparam{flags}{either {\tt wxPROCESS\_DEFAULT} or {\tt wxPROCESS\_REDIRECT}} + \membersection{wxProcess::\destruct{wxProcess}} \func{}{\destruct{wxProcess}}{\void} @@ -184,6 +194,33 @@ It raises a wxWindows event when it isn't overridden. \docparam{status}{The exit code of the process.} +\membersection{wxProcess::Open}\label{wxprocessopen} + +\func{static wxProcess *}{Open}{\param{const wxString\& }{cmd}} + +This static method replaces the standard {\tt popen()} function: it launches +the process specified by the {\it cmd} parameter and returns the wxProcess +object which can be used to retrieve the streams connected to the standard +input, output and error output of the child process. + +If the process couldn't be launched, {\tt NULL} is returned. Note that in any +case the returned pointer should {\bf not} be deleted, rather the process +object will be destroyed automatically when the child process terminates. This +does mean that the child process should be told to quit before the main program +exits to avoid memory leaks. + +\wxheading{Parameters} + +\docparam{cmd}{The command to execute, including optional arguments.} + +\wxheading{Return value} + +A pointer to new wxProcess object or {\tt NULL} on error. + +\wxheading{See also} + +\helpref{wxExecute}{wxexecute} + \membersection{wxProcess::Redirect}\label{wxprocessredirect} \func{void}{Redirect}{\void} diff --git a/include/wx/process.h b/include/wx/process.h index 91c71032eb..67ac9c258f 100644 --- a/include/wx/process.h +++ b/include/wx/process.h @@ -24,6 +24,16 @@ #include "wx/utils.h" // for wxSignal +// the wxProcess creation flags +enum +{ + // no redirection + wxPROCESS_DEFAULT = 0, + + // redirect the IO of the child process + wxPROCESS_REDIRECT = 1 +}; + // ---------------------------------------------------------------------------- // A wxProcess object should be passed to wxExecute - than its OnTerminate() // function will be called when the process terminates. @@ -32,10 +42,27 @@ class WXDLLEXPORT wxProcess : public wxEvtHandler { public: + // kill the process with the given PID + static wxKillError Kill(int pid, wxSignal sig = wxSIGTERM); + + // test if the given process exists + static bool Exists(int pid); + + // this function replaces the standard popen() one: it launches a process + // asynchronously and allows the caller to get the streams connected to its + // std{in|out|err} + // + // on error NULL is returned, in any case the process object will be + // deleted automatically when the process terminates and should *not* be + // deleted by the caller + static wxProcess *Open(const wxString& cmd); + + + // ctors wxProcess(wxEvtHandler *parent = (wxEvtHandler *) NULL, int id = -1) - { Init(parent, id, FALSE); } - wxProcess(wxEvtHandler *parent, bool redirect) - { Init(parent, -1, redirect); } + { Init(parent, id, wxPROCESS_DEFAULT); } + + wxProcess(int flags) { Init(NULL, -1, flags); } virtual ~wxProcess(); @@ -62,23 +89,30 @@ public: void CloseOutput() { delete m_outputStream; m_outputStream = NULL; } // implementation only (for wxExecute) - void SetPipeStreams(wxInputStream *inStream, - wxOutputStream *outStream, + // + // NB: the streams passed here should correspond to the child process + // stdout, stdin and stderr and here the normal naming convention is + // used unlike elsewhere in this class + void SetPipeStreams(wxInputStream *outStream, + wxOutputStream *inStream, wxInputStream *errStream); #endif // wxUSE_STREAMS - // kill the process with the given PID - static wxKillError Kill(int pid, wxSignal sig = wxSIGTERM); - - // test if the given process exists - static bool Exists(int pid); + // for backwards compatibility only, don't use +#if WXWIN_COMPATIBILITY_2_2 + wxProcess(wxEvtHandler *parent, bool redirect) + { Init(parent, -1, redirect ? wxPROCESS_REDIRECT : wxPROCESS_DEFAULT); } +#endif // WXWIN_COMPATIBILITY_2_2 protected: - void Init(wxEvtHandler *parent, int id, bool redirect); + void Init(wxEvtHandler *parent, int id, int flags); int m_id; #if wxUSE_STREAMS + // these streams are connected to stdout, stderr and stdin of the child + // process respectively (yes, m_inputStream corresponds to stdout -- very + // confusing but too late to change now) wxInputStream *m_inputStream, *m_errorStream; wxOutputStream *m_outputStream; diff --git a/src/common/process.cpp b/src/common/process.cpp index 05e24ffb20..d98c7178ef 100644 --- a/src/common/process.cpp +++ b/src/common/process.cpp @@ -47,13 +47,13 @@ IMPLEMENT_DYNAMIC_CLASS(wxProcessEvent, wxEvent) // wxProcess creation // ---------------------------------------------------------------------------- -void wxProcess::Init(wxEvtHandler *parent, int id, bool redirect) +void wxProcess::Init(wxEvtHandler *parent, int id, int flags) { if ( parent ) SetNextHandler(parent); m_id = id; - m_redirect = redirect; + m_redirect = (flags & wxPROCESS_REDIRECT) != 0; #if wxUSE_STREAMS m_inputStream = NULL; @@ -62,6 +62,20 @@ void wxProcess::Init(wxEvtHandler *parent, int id, bool redirect) #endif // wxUSE_STREAMS } +/* static */ +wxProcess *wxProcess::Open(const wxString& cmd) +{ + wxProcess *process = new wxProcess(wxPROCESS_REDIRECT); + if ( !wxExecute(cmd, wxEXEC_ASYNC, process) ) + { + // couldn't launch the process + delete process; + return NULL; + } + + return process; +} + // ---------------------------------------------------------------------------- // wxProcess termination // ---------------------------------------------------------------------------- -- 2.45.2