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