]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/process.cpp
A slightly modified version of Patch #1197468. Keeps track of pending
[wxWidgets.git] / src / common / process.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: process.cpp
3// Purpose: Process termination classes
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$
8// Copyright: (c) Guilhem Lavaux
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "process.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#include "wx/process.h"
32
33// ----------------------------------------------------------------------------
34// event tables and such
35// ----------------------------------------------------------------------------
36
37DEFINE_EVENT_TYPE(wxEVT_END_PROCESS)
38
39IMPLEMENT_DYNAMIC_CLASS(wxProcess, wxEvtHandler)
40IMPLEMENT_DYNAMIC_CLASS(wxProcessEvent, wxEvent)
41
42// ============================================================================
43// wxProcess implementation
44// ============================================================================
45
46// ----------------------------------------------------------------------------
47// wxProcess creation
48// ----------------------------------------------------------------------------
49
50#if WXWIN_COMPATIBILITY_2_2
51
52wxProcess::wxProcess(wxEvtHandler *parent, bool redirect)
53{
54 Init(parent, wxID_ANY, redirect ? wxPROCESS_REDIRECT : wxPROCESS_DEFAULT);
55}
56
57#endif // WXWIN_COMPATIBILITY_2_2
58
59void wxProcess::Init(wxEvtHandler *parent, int id, int flags)
60{
61 if ( parent )
62 SetNextHandler(parent);
63
64 m_id = id;
65 m_redirect = (flags & wxPROCESS_REDIRECT) != 0;
66
67#if wxUSE_STREAMS
68 m_inputStream = NULL;
69 m_errorStream = NULL;
70 m_outputStream = NULL;
71#endif // wxUSE_STREAMS
72}
73
74/* static */
75wxProcess *wxProcess::Open(const wxString& cmd, int flags)
76{
77 wxASSERT_MSG( !(flags & wxEXEC_SYNC), wxT("wxEXEC_SYNC should not be used." ));
78 wxProcess *process = new wxProcess(wxPROCESS_REDIRECT);
79 if ( !wxExecute(cmd, flags, process) )
80 {
81 // couldn't launch the process
82 delete process;
83 return NULL;
84 }
85
86 return process;
87}
88
89// ----------------------------------------------------------------------------
90// wxProcess termination
91// ----------------------------------------------------------------------------
92
93wxProcess::~wxProcess()
94{
95#if wxUSE_STREAMS
96 delete m_inputStream;
97 delete m_errorStream;
98 delete m_outputStream;
99#endif // wxUSE_STREAMS
100}
101
102void wxProcess::OnTerminate(int pid, int status)
103{
104 wxProcessEvent event(m_id, pid, status);
105
106 if ( !ProcessEvent(event) )
107 delete this;
108 //else: the object which processed the event is responsible for deleting
109 // us!
110}
111
112void wxProcess::Detach()
113{
114 SetNextHandler(NULL);
115}
116
117// ----------------------------------------------------------------------------
118// process IO redirection
119// ----------------------------------------------------------------------------
120
121#if wxUSE_STREAMS
122
123void wxProcess::SetPipeStreams(wxInputStream *inputSstream,
124 wxOutputStream *outputStream,
125 wxInputStream *errorStream)
126{
127 m_inputStream = inputSstream;
128 m_errorStream = errorStream;
129 m_outputStream = outputStream;
130}
131
132bool wxProcess::IsInputOpened() const
133{
134 return m_inputStream && m_inputStream->GetLastError() != wxSTREAM_EOF;
135}
136
137bool wxProcess::IsInputAvailable() const
138{
139 return m_inputStream && m_inputStream->CanRead();
140}
141
142bool wxProcess::IsErrorAvailable() const
143{
144 return m_errorStream && m_errorStream->CanRead();
145}
146
147#endif // wxUSE_STREAMS
148
149// ----------------------------------------------------------------------------
150// process killing
151// ----------------------------------------------------------------------------
152
153/* static */
154wxKillError wxProcess::Kill(int pid, wxSignal sig, int flags)
155{
156 wxKillError rc;
157 (void)wxKill(pid, sig, &rc, flags);
158
159 return rc;
160}
161
162/* static */
163bool wxProcess::Exists(int pid)
164{
165 switch ( Kill(pid, wxSIGNONE) )
166 {
167 case wxKILL_OK:
168 case wxKILL_ACCESS_DENIED:
169 return true;
170
171 default:
172 case wxKILL_ERROR:
173 case wxKILL_BAD_SIGNAL:
174 wxFAIL_MSG( _T("unexpected wxProcess::Kill() return code") );
175 // fall through
176
177 case wxKILL_NO_PROCESS:
178 return false;
179 }
180}
181