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