]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/utilsexc.cpp
switching to CreateXXX methods for Controls and to Hit Event Processing, thus support...
[wxWidgets.git] / src / os2 / utilsexc.cpp
... / ...
CommitLineData
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
58struct wxExecuteData
59{
60public:
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
74static 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
99MRESULT 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
133long 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 APIRET rc;
152 TID vTID;
153
154 if (flags & wxEXEC_SYNC)
155 ulExecFlag = EXEC_SYNC;
156 else
157 ulExecFlag = EXEC_ASYNCRESULT;
158
159 rc = ::DosExecPgm( (PCHAR)vLoadError
160 ,sizeof(vLoadError)
161 ,ulExecFlag
162 ,zArgs
163 ,zEnvs
164 ,&vResultCodes
165 ,(PSZ)rCommand.c_str()
166 );
167 if (rc != NO_ERROR)
168 {
169 wxLogSysError(_("Execution of command '%s' failed with error: %ul"), rCommand.c_str(), rc);
170 return 0;
171 }
172// cout << "Executing: " << rCommand.c_str() << endl;
173 // Alloc data
174 wxExecuteData* pData = new wxExecuteData;
175
176 pData->vResultCodes = vResultCodes;
177 pData->hWnd = NULLHANDLE;
178 pData->bState = (flags & wxEXEC_SYNC) != 0;
179 if (flags & wxEXEC_SYNC)
180 {
181 wxASSERT_MSG(!pHandler, wxT("wxProcess param ignored for sync execution"));
182 pData->pHandler = NULL;
183 }
184 else
185 {
186 // may be NULL or not
187 pData->pHandler = pHandler;
188 }
189
190 rc = ::DosCreateThread( &vTID
191 ,(PFNTHREAD)&wxExecuteThread
192 ,(ULONG)pData
193 ,CREATE_READY|STACK_SPARSE
194 ,8192
195 );
196 if (rc != NO_ERROR)
197 {
198 wxLogLastError("CreateThread in wxExecute");
199 delete pData;
200
201 // the process still started up successfully...
202 return vResultCodes.codeTerminate;
203 }
204 if (!(flags & wxEXEC_SYNC))
205 {
206 // return the pid
207 // warning: don't exit your app unless you actively
208 // kill and cleanup you child processes
209 // Maybe detach the process here???
210 // If cmd.exe need to pass DETACH to detach the process here
211 return vResultCodes.codeTerminate;
212 }
213
214 // waiting until command executed
215 ::DosWaitThread(&vTID, DCWW_WAIT);
216
217 ULONG ulExitCode = pData->vResultCodes.codeResult;
218 delete pData;
219
220 // return the exit code
221 return (long)ulExitCode;
222}
223
224long wxExecute(
225 char** ppArgv
226, int flags
227, wxProcess* pHandler
228)
229{
230 wxString sCommand;
231
232 while (*ppArgv != NULL)
233 {
234 sCommand << *ppArgv++ << ' ';
235 }
236 sCommand.RemoveLast();
237 return wxExecute( sCommand
238 ,flags
239 ,pHandler
240 );
241}
242
243bool wxGetFullHostName(
244 wxChar* zBuf
245, int nMaxSize
246)
247{
248#if wxUSE_NET_API
249 char zServer[256];
250 char zComputer[256];
251 unsigned long ulLevel = 0;
252 unsigned char* zBuffer = NULL;
253 unsigned long ulBuffer = 256;
254 unsigned long* pulTotalAvail = NULL;
255
256 NetBios32GetInfo( (const unsigned char*)zServer
257 ,(const unsigned char*)zComputer
258 ,ulLevel
259 ,zBuffer
260 ,ulBuffer
261 ,pulTotalAvail
262 );
263 strncpy(zBuf, zComputer, nMaxSize);
264 zBuf[nMaxSize] = _T('\0');
265#else
266 strcpy(zBuf, "noname");
267#endif
268 return *zBuf ? TRUE : FALSE;
269 return TRUE;
270}
271