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