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