]> git.saurik.com Git - wxWidgets.git/blame - src/os2/utilsexc.cpp
Applied patch [ 1378183 ] Mac: wxNotebook::HitTest off by one
[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 8// Copyright: (c) David Webster
65571936 9// Licence: wxWindows licence
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__
6670f564
WS
30 #include <upm.h>
31 #ifndef __WATCOMC__
32 #include <netcons.h>
33 #include <netbios.h>
34 #endif
9aab8b20 35#endif
c5fb56c0 36
d90895ac 37#include <ctype.h>
9aab8b20
SN
38#ifdef __EMX__
39#include <dirent.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
6670f564
WS
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
6670f564 76static ULONG wxExecuteThread(wxExecuteData* pData)
d90895ac 77{
6670f564
WS
78 ULONG ulRc;
79 PID vPidChild;
dde11e60 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 {
2173b18f 91 wxLogLastError(wxT("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
6670f564
WS
99MRESULT APIENTRY wxExecuteWindowCbk( HWND hWnd,
100 ULONG ulMessage,
101 MPARAM WXUNUSED(wParam),
102 MPARAM lParam)
d90895ac 103{
dde11e60 104 if (ulMessage == wxWM_PROC_TERMINATED)
d90895ac 105 {
dde11e60 106 wxExecuteData* pData = (wxExecuteData *)lParam;
d90895ac 107
dde11e60 108 if (pData->pHandler)
d90895ac 109 {
dde11e60
DW
110 pData->pHandler->OnTerminate( (int)pData->vResultCodes.codeTerminate
111 ,(int)pData->vResultCodes.codeResult
112 );
d90895ac
DW
113 }
114
dde11e60 115 if (pData->bState)
d90895ac
DW
116 {
117 // we're executing synchronously, tell the waiting thread
118 // that the process finished
dde11e60 119 pData->bState = 0;
d90895ac
DW
120 }
121 else
122 {
123 // asynchronous execution - we should do the clean up
dde11e60 124 delete pData;
d90895ac 125 }
dde11e60 126 ::WinDestroyWindow(hWnd); // we don't need it any more
d90895ac 127 }
d90895ac
DW
128 return 0;
129}
130
6670f564
WS
131long wxExecute( const wxString& rCommand,
132 int flags,
133 wxProcess* pHandler)
0e320a79 134{
6670f564 135 if (rCommand.empty())
c5fb56c0 136 {
9aab8b20 137// cout << "empty command in wxExecute." << endl;
c5fb56c0
DW
138 return 0;
139 }
d90895ac
DW
140
141 // create the process
dde11e60
DW
142 UCHAR vLoadError[CCHMAXPATH] = {0};
143 RESULTCODES vResultCodes = {0};
144 ULONG ulExecFlag;
145 PSZ zArgs = NULL;
146 PSZ zEnvs = NULL;
dde11e60 147 APIRET rc;
dde11e60
DW
148 TID vTID;
149
171d29f9 150 if (flags & wxEXEC_SYNC)
dde11e60
DW
151 ulExecFlag = EXEC_SYNC;
152 else
153 ulExecFlag = EXEC_ASYNCRESULT;
154
c5fb56c0
DW
155 rc = ::DosExecPgm( (PCHAR)vLoadError
156 ,sizeof(vLoadError)
157 ,ulExecFlag
158 ,zArgs
159 ,zEnvs
160 ,&vResultCodes
161 ,(PSZ)rCommand.c_str()
162 );
163 if (rc != NO_ERROR)
d90895ac 164 {
c5fb56c0 165 wxLogSysError(_("Execution of command '%s' failed with error: %ul"), rCommand.c_str(), rc);
d90895ac
DW
166 return 0;
167 }
9aab8b20 168// cout << "Executing: " << rCommand.c_str() << endl;
d90895ac 169 // Alloc data
dde11e60 170 wxExecuteData* pData = new wxExecuteData;
d90895ac 171
dde11e60
DW
172 pData->vResultCodes = vResultCodes;
173 pData->hWnd = NULLHANDLE;
171d29f9
VZ
174 pData->bState = (flags & wxEXEC_SYNC) != 0;
175 if (flags & wxEXEC_SYNC)
dde11e60
DW
176 {
177 wxASSERT_MSG(!pHandler, wxT("wxProcess param ignored for sync execution"));
178 pData->pHandler = NULL;
d90895ac
DW
179 }
180 else
181 {
182 // may be NULL or not
dde11e60 183 pData->pHandler = pHandler;
d90895ac
DW
184 }
185
dde11e60
DW
186 rc = ::DosCreateThread( &vTID
187 ,(PFNTHREAD)&wxExecuteThread
188 ,(ULONG)pData
189 ,CREATE_READY|STACK_SPARSE
190 ,8192
191 );
192 if (rc != NO_ERROR)
d90895ac 193 {
2173b18f 194 wxLogLastError(wxT("CreateThread in wxExecute"));
dde11e60 195 delete pData;
d90895ac
DW
196
197 // the process still started up successfully...
dde11e60 198 return vResultCodes.codeTerminate;
d90895ac 199 }
171d29f9 200 if (!(flags & wxEXEC_SYNC))
d90895ac 201 {
d90895ac 202 // return the pid
c5fb56c0
DW
203 // warning: don't exit your app unless you actively
204 // kill and cleanup you child processes
205 // Maybe detach the process here???
206 // If cmd.exe need to pass DETACH to detach the process here
dde11e60 207 return vResultCodes.codeTerminate;
d90895ac 208 }
c5fb56c0
DW
209
210 // waiting until command executed
dde11e60 211 ::DosWaitThread(&vTID, DCWW_WAIT);
d90895ac 212
dde11e60
DW
213 ULONG ulExitCode = pData->vResultCodes.codeResult;
214 delete pData;
d90895ac
DW
215
216 // return the exit code
dde11e60 217 return (long)ulExitCode;
0e320a79 218}
d90895ac 219
dde11e60
DW
220long wxExecute(
221 char** ppArgv
171d29f9 222, int flags
dde11e60
DW
223, wxProcess* pHandler
224)
d90895ac 225{
dde11e60 226 wxString sCommand;
d90895ac 227
dde11e60 228 while (*ppArgv != NULL)
d90895ac 229 {
0fba44b4
DW
230 wxString sArg((wxChar*)(*ppArgv++));
231
232
233 sCommand << sArg.c_str() << ' ';
d90895ac 234 }
dde11e60
DW
235 sCommand.RemoveLast();
236 return wxExecute( sCommand
171d29f9 237 ,flags
dde11e60
DW
238 ,pHandler
239 );
d90895ac
DW
240}
241
6670f564
WS
242bool wxGetFullHostName( wxChar* zBuf,
243 int nMaxSize)
d90895ac 244{
dde11e60
DW
245#if wxUSE_NET_API
246 char zServer[256];
247 char zComputer[256];
909b4f08 248 unsigned long ulLevel = 0;
9dea36ef
DW
249 unsigned char* zBuffer = NULL;
250 unsigned long ulBuffer = 256;
251 unsigned long* pulTotalAvail = NULL;
dde11e60
DW
252
253 NetBios32GetInfo( (const unsigned char*)zServer
254 ,(const unsigned char*)zComputer
909b4f08 255 ,ulLevel
dde11e60 256 ,zBuffer
909b4f08
DW
257 ,ulBuffer
258 ,pulTotalAvail
dde11e60
DW
259 );
260 strncpy(zBuf, zComputer, nMaxSize);
261 zBuf[nMaxSize] = _T('\0');
262#else
6670f564 263 wxUnusedVar(nMaxSize);
0fba44b4 264 strcpy((char*)zBuf, "noname");
dde11e60 265#endif
6670f564 266 return *zBuf ? true : false;
d90895ac 267}