*** empty log message ***
[wxWidgets.git] / src / os2 / utilsexc.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: utilsexec.cpp
3 // Purpose: Various utilities
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/17/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include "wx/setup.h"
17 #include "wx/utils.h"
18 #include "wx/app.h"
19 #include "wx/intl.h"
20 #endif
21
22 #include "wx/log.h"
23
24 #include "wx/process.h"
25
26 #include "wx/os2/private.h"
27
28 #define INCL_DOS
29 #include <os2.h>
30
31 #include <ctype.h>
32 #include <direct.h>
33
34 #include <sys/stat.h>
35 #include <io.h>
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <errno.h>
41 #include <stdarg.h>
42
43 // this message is sent when the process we're waiting for terminates
44 #define wxWM_PROC_TERMINATED (WM_USER + 10000)
45
46 // structure describing the process we're being waiting for
47 struct wxExecuteData
48 {
49 public:
50 ~wxExecuteData()
51 {
52 // TODO:
53 /*
54 if ( !::CloseHandle(hProcess) )
55 {
56 wxLogLastError("CloseHandle(hProcess)");
57 }
58 */
59 }
60
61 HWND hWnd; // window to send wxWM_PROC_TERMINATED to
62 HANDLE hProcess; // handle of the process
63 DWORD dwProcessId; // pid of the process
64 wxProcess *handler;
65 DWORD dwExitCode; // the exit code of the process
66 bool state; // set to FALSE when the process finishes
67 };
68
69
70 static DWORD wxExecuteThread(wxExecuteData *data)
71 {
72 // TODO:
73 /*
74 WaitForSingleObject(data->hProcess, INFINITE);
75
76 // get the exit code
77 if ( !GetExitCodeProcess(data->hProcess, &data->dwExitCode) )
78 {
79 wxLogLastError("GetExitCodeProcess");
80 }
81
82 wxASSERT_MSG( data->dwExitCode != STILL_ACTIVE,
83 wxT("process should have terminated") );
84
85 // send a message indicating process termination to the window
86 SendMessage(data->hWnd, wxWM_PROC_TERMINATED, 0, (LPARAM)data);
87 */
88 return 0;
89 }
90
91 // window procedure of a hidden window which is created just to receive
92 // the notification message when a process exits
93 MRESULT APIENTRY wxExecuteWindowCbk(HWND hWnd, UINT message,
94 MPARAM wParam, MPARAM lParam)
95 {
96 if ( message == wxWM_PROC_TERMINATED )
97 {
98 // DestroyWindow(hWnd); // we don't need it any more
99
100 wxExecuteData *data = (wxExecuteData *)lParam;
101 if ( data->handler )
102 {
103 data->handler->OnTerminate((int)data->dwProcessId,
104 (int)data->dwExitCode);
105 }
106
107 if ( data->state )
108 {
109 // we're executing synchronously, tell the waiting thread
110 // that the process finished
111 data->state = 0;
112 }
113 else
114 {
115 // asynchronous execution - we should do the clean up
116 delete data;
117 }
118 }
119
120 return 0;
121 }
122
123 extern wxChar wxPanelClassName[];
124
125 long wxExecute(const wxString& command, bool sync, wxProcess *handler)
126 {
127 wxCHECK_MSG( !!command, 0, wxT("empty command in wxExecute") );
128
129 // the old code is disabled because we really need a process handle
130 // if we want to execute it asynchronously or even just get its
131 // return code and for this we must use CreateProcess() and not
132 // ShellExecute()
133
134 // create the process
135 // TODO:
136 /*
137 STARTUPINFO si;
138 memset(&si, 0, sizeof(si));
139 si.cb = sizeof(si);
140
141 PROCESS_INFORMATION pi;
142
143 if ( ::CreateProcess(
144 NULL, // application name (use only cmd line)
145 (wxChar *)command.c_str(), // full command line
146 NULL, // security attributes: defaults for both
147 NULL, // the process and its main thread
148 FALSE, // don't inherit handles
149 CREATE_DEFAULT_ERROR_MODE, // flags
150 NULL, // environment (use the same)
151 NULL, // current directory (use the same)
152 &si, // startup info (unused here)
153 &pi // process info
154 ) == 0 )
155 {
156 wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
157
158 return 0;
159 }
160
161 // close unneeded handle
162 if ( !::CloseHandle(pi.hThread) )
163 wxLogLastError("CloseHandle(hThread)");
164
165 // create a hidden window to receive notification about process
166 // termination
167 HWND hwnd = ::CreateWindow(wxPanelClassName, NULL, 0, 0, 0, 0, 0, NULL,
168 (HMENU)NULL, wxGetInstance(), 0);
169 wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );
170
171 FARPROC ExecuteWindowInstance = MakeProcInstance((FARPROC)wxExecuteWindowCbk,
172 wxGetInstance());
173
174 ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) ExecuteWindowInstance);
175
176 // Alloc data
177 wxExecuteData *data = new wxExecuteData;
178 data->hProcess = pi.hProcess;
179 data->dwProcessId = pi.dwProcessId;
180 data->hWnd = hwnd;
181 data->state = sync;
182 if ( sync )
183 {
184 wxASSERT_MSG( !handler, wxT("wxProcess param ignored for sync execution") );
185
186 data->handler = NULL;
187 }
188 else
189 {
190 // may be NULL or not
191 data->handler = handler;
192 }
193
194 DWORD tid;
195 HANDLE hThread = ::CreateThread(NULL,
196 0,
197 (LPTHREAD_START_ROUTINE)wxExecuteThread,
198 (void *)data,
199 0,
200 &tid);
201
202 if ( !hThread )
203 {
204 wxLogLastError("CreateThread in wxExecute");
205
206 DestroyWindow(hwnd);
207 delete data;
208
209 // the process still started up successfully...
210 return pi.dwProcessId;
211 }
212
213 if ( !sync )
214 {
215 // clean up will be done when the process terminates
216
217 // return the pid
218 return pi.dwProcessId;
219 }
220
221 // waiting until command executed
222 while ( data->state )
223 wxYield();
224
225 DWORD dwExitCode = data->dwExitCode;
226 delete data;
227
228 // return the exit code
229 return dwExitCode;
230 */
231 return 0;
232 }
233
234 long wxExecute(char **argv, bool sync, wxProcess *handler)
235 {
236 wxString command;
237
238 while ( *argv != NULL )
239 {
240 command << *argv++ << ' ';
241 }
242
243 command.RemoveLast();
244
245 return wxExecute(command, sync, handler);
246 }
247
248 bool wxGetFullHostName(wxChar *buf, int maxSize)
249 {
250 DWORD nSize = maxSize ;
251 // TODO:
252 /*
253 if ( !::GetComputerName(buf, &nSize) )
254 {
255 wxLogLastError("GetComputerName");
256
257 return FALSE;
258 }
259 */
260 return TRUE;
261 }
262