wxOS2 with Open Watcom: correct PCH usage, missing headers, warning fixes, source...
[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 #ifndef __WATCOMC__
32 #include <netcons.h>
33 #include <netbios.h>
34 #endif
35 #endif
36
37 #include <ctype.h>
38 #ifdef __EMX__
39 #include <dirent.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(wxExecuteData* pData)
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(wxT("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( HWND hWnd,
100 ULONG ulMessage,
101 MPARAM WXUNUSED(wParam),
102 MPARAM lParam)
103 {
104 if (ulMessage == wxWM_PROC_TERMINATED)
105 {
106 wxExecuteData* pData = (wxExecuteData *)lParam;
107
108 if (pData->pHandler)
109 {
110 pData->pHandler->OnTerminate( (int)pData->vResultCodes.codeTerminate
111 ,(int)pData->vResultCodes.codeResult
112 );
113 }
114
115 if (pData->bState)
116 {
117 // we're executing synchronously, tell the waiting thread
118 // that the process finished
119 pData->bState = 0;
120 }
121 else
122 {
123 // asynchronous execution - we should do the clean up
124 delete pData;
125 }
126 ::WinDestroyWindow(hWnd); // we don't need it any more
127 }
128 return 0;
129 }
130
131 long wxExecute( const wxString& rCommand,
132 int flags,
133 wxProcess* pHandler)
134 {
135 if (rCommand.empty())
136 {
137 // cout << "empty command in wxExecute." << endl;
138 return 0;
139 }
140
141 // create the process
142 UCHAR vLoadError[CCHMAXPATH] = {0};
143 RESULTCODES vResultCodes = {0};
144 ULONG ulExecFlag;
145 PSZ zArgs = NULL;
146 PSZ zEnvs = NULL;
147 APIRET rc;
148 TID vTID;
149
150 if (flags & wxEXEC_SYNC)
151 ulExecFlag = EXEC_SYNC;
152 else
153 ulExecFlag = EXEC_ASYNCRESULT;
154
155 rc = ::DosExecPgm( (PCHAR)vLoadError
156 ,sizeof(vLoadError)
157 ,ulExecFlag
158 ,zArgs
159 ,zEnvs
160 ,&vResultCodes
161 ,(PSZ)rCommand.c_str()
162 );
163 if (rc != NO_ERROR)
164 {
165 wxLogSysError(_("Execution of command '%s' failed with error: %ul"), rCommand.c_str(), rc);
166 return 0;
167 }
168 // cout << "Executing: " << rCommand.c_str() << endl;
169 // Alloc data
170 wxExecuteData* pData = new wxExecuteData;
171
172 pData->vResultCodes = vResultCodes;
173 pData->hWnd = NULLHANDLE;
174 pData->bState = (flags & wxEXEC_SYNC) != 0;
175 if (flags & wxEXEC_SYNC)
176 {
177 wxASSERT_MSG(!pHandler, wxT("wxProcess param ignored for sync execution"));
178 pData->pHandler = NULL;
179 }
180 else
181 {
182 // may be NULL or not
183 pData->pHandler = pHandler;
184 }
185
186 rc = ::DosCreateThread( &vTID
187 ,(PFNTHREAD)&wxExecuteThread
188 ,(ULONG)pData
189 ,CREATE_READY|STACK_SPARSE
190 ,8192
191 );
192 if (rc != NO_ERROR)
193 {
194 wxLogLastError(wxT("CreateThread in wxExecute"));
195 delete pData;
196
197 // the process still started up successfully...
198 return vResultCodes.codeTerminate;
199 }
200 if (!(flags & wxEXEC_SYNC))
201 {
202 // return the pid
203 // warning: don't exit your app unless you actively
204 // kill and cleanup you child processes
205 // Maybe detach the process here???
206 // If cmd.exe need to pass DETACH to detach the process here
207 return vResultCodes.codeTerminate;
208 }
209
210 // waiting until command executed
211 ::DosWaitThread(&vTID, DCWW_WAIT);
212
213 ULONG ulExitCode = pData->vResultCodes.codeResult;
214 delete pData;
215
216 // return the exit code
217 return (long)ulExitCode;
218 }
219
220 long wxExecute(
221 char** ppArgv
222 , int flags
223 , wxProcess* pHandler
224 )
225 {
226 wxString sCommand;
227
228 while (*ppArgv != NULL)
229 {
230 wxString sArg((wxChar*)(*ppArgv++));
231
232
233 sCommand << sArg.c_str() << ' ';
234 }
235 sCommand.RemoveLast();
236 return wxExecute( sCommand
237 ,flags
238 ,pHandler
239 );
240 }
241
242 bool wxGetFullHostName( wxChar* zBuf,
243 int nMaxSize)
244 {
245 #if wxUSE_NET_API
246 char zServer[256];
247 char zComputer[256];
248 unsigned long ulLevel = 0;
249 unsigned char* zBuffer = NULL;
250 unsigned long ulBuffer = 256;
251 unsigned long* pulTotalAvail = NULL;
252
253 NetBios32GetInfo( (const unsigned char*)zServer
254 ,(const unsigned char*)zComputer
255 ,ulLevel
256 ,zBuffer
257 ,ulBuffer
258 ,pulTotalAvail
259 );
260 strncpy(zBuf, zComputer, nMaxSize);
261 zBuf[nMaxSize] = _T('\0');
262 #else
263 wxUnusedVar(nMaxSize);
264 strcpy((char*)zBuf, "noname");
265 #endif
266 return *zBuf ? true : false;
267 }