]> git.saurik.com Git - wxWidgets.git/blob - src/common/process.cpp
Fix (workaround?) for rpmspec.
[wxWidgets.git] / src / common / process.cpp
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
37 DEFINE_EVENT_TYPE(wxEVT_END_PROCESS)
38
39 IMPLEMENT_DYNAMIC_CLASS(wxProcess, wxEvtHandler)
40 IMPLEMENT_DYNAMIC_CLASS(wxProcessEvent, wxEvent)
41
42 // ============================================================================
43 // wxProcess implementation
44 // ============================================================================
45
46 // ----------------------------------------------------------------------------
47 // wxProcess creation
48 // ----------------------------------------------------------------------------
49
50 #if WXWIN_COMPATIBILITY_2_2
51
52 wxProcess::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
59 void 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 */
75 wxProcess *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
93 wxProcess::~wxProcess()
94 {
95 #if wxUSE_STREAMS
96 delete m_inputStream;
97 delete m_errorStream;
98 delete m_outputStream;
99 #endif // wxUSE_STREAMS
100 }
101
102 void 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
112 void wxProcess::Detach()
113 {
114 SetNextHandler(NULL);
115 }
116
117 // ----------------------------------------------------------------------------
118 // process IO redirection
119 // ----------------------------------------------------------------------------
120
121 #if wxUSE_STREAMS
122
123 void 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
132 bool wxProcess::IsInputOpened() const
133 {
134 return m_inputStream && m_inputStream->GetLastError() != wxSTREAM_EOF;
135 }
136
137 bool wxProcess::IsInputAvailable() const
138 {
139 return m_inputStream && m_inputStream->CanRead();
140 }
141
142 bool 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 */
154 wxKillError 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 */
163 bool 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