]> git.saurik.com Git - wxWidgets.git/blob - src/os2/utilsexc.cpp
Completely reworked OS/2 thread implementation.
[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 licence
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 PURE_32
29 #ifndef __EMX__
30 #include <upm.h>
31 #include <netcons.h>
32 #include <netbios.h>
33 #endif
34
35 #include <ctype.h>
36 #ifdef __EMX__
37 #include <dirent.h>
38 #endif
39
40 #include <sys/stat.h>
41 #include <io.h>
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <stdarg.h>
48
49
50 // this message is sent when the process we're waiting for terminates
51 #define wxWM_PROC_TERMINATED (WM_USER + 10000)
52
53 #ifndef NO_ERROR
54 # define NO_ERROR 0
55 #endif
56
57 // structure describing the process we're being waiting for
58 struct wxExecuteData
59 {
60 public:
61 ~wxExecuteData()
62 {
63 // cout << "Closing thread: " << endl;
64 DosExit(EXIT_PROCESS, 0);
65 }
66
67 HWND hWnd; // window to send wxWM_PROC_TERMINATED to [not used]
68 RESULTCODES vResultCodes;
69 wxProcess* pHandler;
70 ULONG ulExitCode; // the exit code of the process
71 bool bState; // set to FALSE when the process finishes
72 };
73
74 static ULONG wxExecuteThread(
75 wxExecuteData* pData
76 )
77 {
78 ULONG ulRc;
79 PID vPidChild;
80
81 // cout << "Executing thread: " << endl;
82
83 ulRc = ::DosWaitChild( DCWA_PROCESSTREE
84 ,DCWW_NOWAIT
85 ,&pData->vResultCodes
86 ,&vPidChild
87 ,pData->vResultCodes.codeTerminate // process PID to look at
88 );
89 if (ulRc != NO_ERROR)
90 {
91 wxLogLastError("DosWaitChild");
92 }
93 delete pData;
94 return 0;
95 }
96
97 // window procedure of a hidden window which is created just to receive
98 // the notification message when a process exits
99 MRESULT APIENTRY wxExecuteWindowCbk(
100 HWND hWnd
101 , ULONG ulMessage
102 , MPARAM wParam
103 , MPARAM lParam
104 )
105 {
106 if (ulMessage == wxWM_PROC_TERMINATED)
107 {
108 wxExecuteData* pData = (wxExecuteData *)lParam;
109
110 if (pData->pHandler)
111 {
112 pData->pHandler->OnTerminate( (int)pData->vResultCodes.codeTerminate
113 ,(int)pData->vResultCodes.codeResult
114 );
115 }
116
117 if (pData->bState)
118 {
119 // we're executing synchronously, tell the waiting thread
120 // that the process finished
121 pData->bState = 0;
122 }
123 else
124 {
125 // asynchronous execution - we should do the clean up
126 delete pData;
127 }
128 ::WinDestroyWindow(hWnd); // we don't need it any more
129 }
130 return 0;
131 }
132
133 long wxExecute(
134 const wxString& rCommand
135 , int flags
136 , wxProcess* pHandler
137 )
138 {
139 if (rCommand.IsEmpty())
140 {
141 // cout << "empty command in wxExecute." << endl;
142 return 0;
143 }
144
145 // create the process
146 UCHAR vLoadError[CCHMAXPATH] = {0};
147 RESULTCODES vResultCodes = {0};
148 ULONG ulExecFlag;
149 PSZ zArgs = NULL;
150 PSZ zEnvs = NULL;
151 ULONG ulWindowId;
152 APIRET rc;
153 PFNWP pOldProc;
154 TID vTID;
155
156 if (flags & wxEXEC_SYNC)
157 ulExecFlag = EXEC_SYNC;
158 else
159 ulExecFlag = EXEC_ASYNCRESULT;
160
161 rc = ::DosExecPgm( (PCHAR)vLoadError
162 ,sizeof(vLoadError)
163 ,ulExecFlag
164 ,zArgs
165 ,zEnvs
166 ,&vResultCodes
167 ,(PSZ)rCommand.c_str()
168 );
169 if (rc != NO_ERROR)
170 {
171 wxLogSysError(_("Execution of command '%s' failed with error: %ul"), rCommand.c_str(), rc);
172 return 0;
173 }
174 // cout << "Executing: " << rCommand.c_str() << endl;
175 // Alloc data
176 wxExecuteData* pData = new wxExecuteData;
177
178 pData->vResultCodes = vResultCodes;
179 pData->hWnd = NULLHANDLE;
180 pData->bState = (flags & wxEXEC_SYNC) != 0;
181 if (flags & wxEXEC_SYNC)
182 {
183 wxASSERT_MSG(!pHandler, wxT("wxProcess param ignored for sync execution"));
184 pData->pHandler = NULL;
185 }
186 else
187 {
188 // may be NULL or not
189 pData->pHandler = pHandler;
190 }
191
192 rc = ::DosCreateThread( &vTID
193 ,(PFNTHREAD)&wxExecuteThread
194 ,(ULONG)pData
195 ,CREATE_READY|STACK_SPARSE
196 ,8192
197 );
198 if (rc != NO_ERROR)
199 {
200 wxLogLastError("CreateThread in wxExecute");
201 delete pData;
202
203 // the process still started up successfully...
204 return vResultCodes.codeTerminate;
205 }
206 if (!(flags & wxEXEC_SYNC))
207 {
208 // return the pid
209 // warning: don't exit your app unless you actively
210 // kill and cleanup you child processes
211 // Maybe detach the process here???
212 // If cmd.exe need to pass DETACH to detach the process here
213 return vResultCodes.codeTerminate;
214 }
215
216 // waiting until command executed
217 ::DosWaitThread(&vTID, DCWW_WAIT);
218
219 ULONG ulExitCode = pData->vResultCodes.codeResult;
220 delete pData;
221
222 // return the exit code
223 return (long)ulExitCode;
224 }
225
226 long wxExecute(
227 char** ppArgv
228 , int flags
229 , wxProcess* pHandler
230 )
231 {
232 wxString sCommand;
233
234 while (*ppArgv != NULL)
235 {
236 sCommand << *ppArgv++ << ' ';
237 }
238 sCommand.RemoveLast();
239 return wxExecute( sCommand
240 ,flags
241 ,pHandler
242 );
243 }
244
245 bool wxGetFullHostName(
246 wxChar* zBuf
247 , int nMaxSize
248 )
249 {
250 #if wxUSE_NET_API
251 char zServer[256];
252 char zComputer[256];
253 unsigned long ulLevel = 0;
254 unsigned char* zBuffer = NULL;
255 unsigned long ulBuffer = 256;
256 unsigned long* pulTotalAvail = NULL;
257
258 NetBios32GetInfo( (const unsigned char*)zServer
259 ,(const unsigned char*)zComputer
260 ,ulLevel
261 ,zBuffer
262 ,ulBuffer
263 ,pulTotalAvail
264 );
265 strncpy(zBuf, zComputer, nMaxSize);
266 zBuf[nMaxSize] = _T('\0');
267 #else
268 strcpy(zBuf, "noname");
269 #endif
270 return *zBuf ? TRUE : FALSE;
271 return TRUE;
272 }
273