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