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