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