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