1977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly/*************************************************************************** 2977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** The BSD 3-Clause License. http://www.opensource.org/licenses/BSD-3-Clause 3977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** 4977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** This file is part of 'mingw-builds' project. 5977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** Copyright (c) 2011,2012,2013 by niXman (i dotty nixman doggy gmail dotty com) 6977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** All rights reserved. 7977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** 8977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** Project: mingw-builds ( http://sourceforge.net/projects/mingwbuilds/ ) 9977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** 10977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** Redistribution and use in source and binary forms, with or without 11977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** modification, are permitted provided that the following conditions are met: 12977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** - Redistributions of source code must retain the above copyright 13977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** notice, this list of conditions and the following disclaimer. 14977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** - Redistributions in binary form must reproduce the above copyright 15977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** notice, this list of conditions and the following disclaimer in 16977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** the documentation and/or other materials provided with the distribution. 17977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** - Neither the name of the 'mingw-builds' nor the names of its contributors may 18977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** be used to endorse or promote products derived from this software 19977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** without specific prior written permission. 20977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** 21977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** A PARTICULAR PURPOSE ARE DISCLAIMED. 25977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 26977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 31977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly** 33977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly***************************************************************************/ 34977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 35977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#include <windows.h> 36977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 37977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#include <stdio.h> 38977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#include <strings.h> 39977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 40977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#ifdef _DEBUG 41977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly #define dbg_printf(...) printf(__VA_ARGS__) 42977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#else 43977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly #define dbg_printf(...) do {} while(0) 44977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#endif 45977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 46977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly// When built for the Android NDK, values are 47977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly// passed in on the GCC commandline, and when 48977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly// built for mingw-builds, these defaults are 49977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly// used. 50977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#ifndef GDB_TO_PYTHON_REL_DIR 51977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly #define GDB_TO_PYTHON_REL_DIR "..\\opt\\bin" 52977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#endif 53977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 54977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#ifndef GDB_EXECUTABLE_ORIG_FILENAME 55977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly #define GDB_EXECUTABLE_ORIG_FILENAME "gdborig.exe" 56977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#endif 57977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 58977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#ifndef PYTHONHOME_REL_DIR 59977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly #define PYTHONHOME_REL_DIR "..\\opt" 60977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#endif 61977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 62977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly#define DIE_IF_FALSE(var) \ 63977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly do { \ 64977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly if ( !(var) ) { \ 65977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly fprintf(stderr, "%s(%d)[%d]: expression \"%s\" fail. terminate.\n" \ 66977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,__FILE__ \ 67977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,__LINE__ \ 68977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,GetLastError() \ 69977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,#var \ 70977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); \ 71977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly exit(1); \ 72977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly } \ 73977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly } while (0) 74977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 75977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnellyint main(int argc, char** argv) { 76977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly enum { 77977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly envbufsize = 1024*32 78977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,exebufsize = 1024 79977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,cmdbufsize = envbufsize 80977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly }; 81977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 82977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly char *envbuf, *sep, *resbuf, *cmdbuf; 83977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DWORD len, exitCode; 84977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly STARTUPINFO si; 85977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly PROCESS_INFORMATION pi; 86977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 87977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 8885869dfbfb859b7f42948aaa1d46a86b9a9b743aAndrew Hsieh (envbuf = (char *)malloc(envbufsize)) 89977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 90977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 9185869dfbfb859b7f42948aaa1d46a86b9a9b743aAndrew Hsieh (cmdbuf = (char *)malloc(cmdbufsize)) 92977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 93977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly *cmdbuf = 0; 94977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 95977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 96977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly GetEnvironmentVariable("PATH", envbuf, envbufsize) 97977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 98977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly dbg_printf("env: %s\n", envbuf); 99977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 100977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 101977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly GetModuleFileName(0, cmdbuf, exebufsize) 102977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 103977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly dbg_printf("curdir: %s\n", cmdbuf); 104977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 105977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 106977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly (sep = strrchr(cmdbuf, '\\')) 107977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 108977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly *(sep+1) = 0; 109977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly strcat(cmdbuf, GDB_TO_PYTHON_REL_DIR); 110977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly dbg_printf("sep: %s\n", cmdbuf); 111977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 112977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly len = strlen(envbuf)+strlen(cmdbuf) 113977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly +1 /* for envronment separator */ 114977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly +1; /* for zero-terminator */ 115977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 116977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 11785869dfbfb859b7f42948aaa1d46a86b9a9b743aAndrew Hsieh (resbuf = (char *)malloc(len)) 118977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 119977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 120977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 121977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly (snprintf(resbuf, len, "%s;%s", cmdbuf, envbuf) > 0) 122977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 123977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly dbg_printf("PATH: %s\n", resbuf); 124977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 125977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 126977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly SetEnvironmentVariable("PATH", resbuf) 127977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 128977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 129977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly *(sep+1) = 0; 130977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly strcat(cmdbuf, PYTHONHOME_REL_DIR); 131977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly dbg_printf("PYTHONHOME: %s\n", cmdbuf); 132977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 133977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly SetEnvironmentVariable("PYTHONHOME", cmdbuf) 134977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 135977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 136977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly *(sep+1) = 0; 137977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly strcat(cmdbuf, GDB_EXECUTABLE_ORIG_FILENAME" "); 138977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 139977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly if ( argc > 1 ) { 140977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly for ( ++argv; *argv; ++argv ) { 141977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly len = strlen(cmdbuf); 142977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly snprintf(cmdbuf+len, cmdbufsize-len, "%s ", *argv); 143977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly } 144977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly } 145977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly dbg_printf("cmd: %s\n", cmdbuf); 146977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 147977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly HANDLE ghJob = CreateJobObject(NULL, "Gdb-Wrapper\0"/*NULL*/); 148977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly if ( ghJob == NULL ) { 149977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly fprintf(stderr, "Could not create job object\n"); 150977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly } 151977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly else{ 152977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; 153977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly // Configure all child processes associated with the job to terminate when the last handle to the job is closed 154977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; 155977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly if ( SetInformationJobObject(ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)) == 0 ) { 156977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly fprintf(stderr, "Could not SetInformationJobObject\n"); 157977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly } 158977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly } 159977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 160977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly memset(&si, 0, sizeof(si)); 161977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly si.cb = sizeof(si); 162977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly si.dwFlags |= STARTF_USESTDHANDLES; 163977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); 164977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); 165977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly si.hStdError = GetStdHandle(STD_ERROR_HANDLE); 166977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 167977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly memset(&pi, 0, sizeof(pi)); 168977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 169977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 170977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly CreateProcess( 171977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 0 // exe name 172977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,cmdbuf // command line 173977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,0 // process security attributes 174977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,0 // primary thread security attributes 175977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,TRUE // handles are inherited 176977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,0 // creation flags 177977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,0 // use parent's environment 178977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,0 // use parent's current directory 179977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,&si // STARTUPINFO pointer 180977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ,&pi // receives PROCESS_INFORMATION 181977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ) 182977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 183977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 184977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly if ( ghJob != NULL ) 185977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly if ( AssignProcessToJobObject(ghJob, pi.hProcess) == 0 ) { 186977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly fprintf(stderr, "Could not AssignProcessToObject\n"); 187977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly } 188977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 189977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly // Do not handle Ctrl-C in the wrapper 190977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly SetConsoleCtrlHandler(NULL, TRUE); 191977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 192977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly WaitForSingleObject(pi.hProcess, INFINITE); 193977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 194977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly DIE_IF_FALSE( 195977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly GetExitCodeProcess(pi.hProcess, &exitCode) 196977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly ); 197977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 198977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly if ( ghJob != NULL ) 199977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly CloseHandle(ghJob); 200977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly CloseHandle( pi.hProcess ); 201977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly CloseHandle( pi.hThread ); 202977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 203977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly free(envbuf); 204977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly free(resbuf); 205977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly free(cmdbuf); 206977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 207977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly dbg_printf("exiting with exitCode %d", exitCode); 208977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly 209977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly return exitCode; 210977eaeb520cf5aa5abf33a320672b5b103c7b228Ray Donnelly} 211