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