210 lines
5.9 KiB
C
210 lines
5.9 KiB
C
/***************************************************************************
|
|
** The BSD 3-Clause License. http://www.opensource.org/licenses/BSD-3-Clause
|
|
**
|
|
** This file is part of 'mingw-builds' project.
|
|
** Copyright (c) 2011,2012,2013 by niXman (i dotty nixman doggy gmail dotty com)
|
|
** All rights reserved.
|
|
**
|
|
** Project: mingw-builds ( http://sourceforge.net/projects/mingwbuilds/ )
|
|
**
|
|
** Redistribution and use in source and binary forms, with or without
|
|
** modification, are permitted provided that the following conditions are met:
|
|
** - Redistributions of source code must retain the above copyright
|
|
** notice, this list of conditions and the following disclaimer.
|
|
** - Redistributions in binary form must reproduce the above copyright
|
|
** notice, this list of conditions and the following disclaimer in
|
|
** the documentation and/or other materials provided with the distribution.
|
|
** - Neither the name of the 'mingw-builds' nor the names of its contributors may
|
|
** be used to endorse or promote products derived from this software
|
|
** without specific prior written permission.
|
|
**
|
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
** A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
** IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
|
** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
**
|
|
***************************************************************************/
|
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
#include <strings.h>
|
|
|
|
#ifdef _DEBUG
|
|
#define dbg_printf(...) printf(__VA_ARGS__)
|
|
#else
|
|
#define dbg_printf(...) do {} while(0)
|
|
#endif
|
|
|
|
// When built for the Android NDK, values are
|
|
// passed in on the GCC commandline, and when
|
|
// built for mingw-builds, these defaults are
|
|
// used.
|
|
#ifndef GDB_TO_PYTHON_REL_DIR
|
|
#define GDB_TO_PYTHON_REL_DIR "..\\opt\\bin"
|
|
#endif
|
|
|
|
#ifndef GDB_EXECUTABLE_ORIG_FILENAME
|
|
#define GDB_EXECUTABLE_ORIG_FILENAME "gdborig.exe"
|
|
#endif
|
|
|
|
#ifndef PYTHONHOME_REL_DIR
|
|
#define PYTHONHOME_REL_DIR "..\\opt"
|
|
#endif
|
|
|
|
#define DIE_IF_FALSE(var) \
|
|
do { \
|
|
if ( !(var) ) { \
|
|
fprintf(stderr, "%s(%d)[%d]: expression \"%s\" fail. terminate.\n" \
|
|
,__FILE__ \
|
|
,__LINE__ \
|
|
,GetLastError() \
|
|
,#var \
|
|
); \
|
|
exit(1); \
|
|
} \
|
|
} while (0)
|
|
|
|
int main(int argc, char** argv) {
|
|
enum {
|
|
envbufsize = 1024*32
|
|
,exebufsize = 1024
|
|
,cmdbufsize = envbufsize
|
|
};
|
|
|
|
char *envbuf, *sep, *resbuf, *cmdbuf;
|
|
DWORD len, exitCode;
|
|
STARTUPINFO si;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
DIE_IF_FALSE(
|
|
(envbuf = (char *)malloc(envbufsize))
|
|
);
|
|
DIE_IF_FALSE(
|
|
(cmdbuf = (char *)malloc(cmdbufsize))
|
|
);
|
|
*cmdbuf = 0;
|
|
|
|
DIE_IF_FALSE(
|
|
GetEnvironmentVariable("PATH", envbuf, envbufsize)
|
|
);
|
|
dbg_printf("env: %s\n", envbuf);
|
|
|
|
DIE_IF_FALSE(
|
|
GetModuleFileName(0, cmdbuf, exebufsize)
|
|
);
|
|
dbg_printf("curdir: %s\n", cmdbuf);
|
|
|
|
DIE_IF_FALSE(
|
|
(sep = strrchr(cmdbuf, '\\'))
|
|
);
|
|
*(sep+1) = 0;
|
|
strcat(cmdbuf, GDB_TO_PYTHON_REL_DIR);
|
|
dbg_printf("sep: %s\n", cmdbuf);
|
|
|
|
len = strlen(envbuf)+strlen(cmdbuf)
|
|
+1 /* for envronment separator */
|
|
+1; /* for zero-terminator */
|
|
|
|
DIE_IF_FALSE(
|
|
(resbuf = (char *)malloc(len))
|
|
);
|
|
|
|
DIE_IF_FALSE(
|
|
(snprintf(resbuf, len, "%s;%s", cmdbuf, envbuf) > 0)
|
|
);
|
|
dbg_printf("PATH: %s\n", resbuf);
|
|
|
|
DIE_IF_FALSE(
|
|
SetEnvironmentVariable("PATH", resbuf)
|
|
);
|
|
|
|
*(sep+1) = 0;
|
|
strcat(cmdbuf, PYTHONHOME_REL_DIR);
|
|
dbg_printf("PYTHONHOME: %s\n", cmdbuf);
|
|
DIE_IF_FALSE(
|
|
SetEnvironmentVariable("PYTHONHOME", cmdbuf)
|
|
);
|
|
|
|
*(sep+1) = 0;
|
|
strcat(cmdbuf, GDB_EXECUTABLE_ORIG_FILENAME" ");
|
|
|
|
if ( argc > 1 ) {
|
|
for ( ++argv; *argv; ++argv ) {
|
|
len = strlen(cmdbuf);
|
|
snprintf(cmdbuf+len, cmdbufsize-len, "%s ", *argv);
|
|
}
|
|
}
|
|
dbg_printf("cmd: %s\n", cmdbuf);
|
|
|
|
HANDLE ghJob = CreateJobObject(NULL, "Gdb-Wrapper\0"/*NULL*/);
|
|
if ( ghJob == NULL ) {
|
|
fprintf(stderr, "Could not create job object\n");
|
|
}
|
|
else{
|
|
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
|
|
// Configure all child processes associated with the job to terminate when the last handle to the job is closed
|
|
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
|
if ( SetInformationJobObject(ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)) == 0 ) {
|
|
fprintf(stderr, "Could not SetInformationJobObject\n");
|
|
}
|
|
}
|
|
|
|
memset(&si, 0, sizeof(si));
|
|
si.cb = sizeof(si);
|
|
si.dwFlags |= STARTF_USESTDHANDLES;
|
|
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
|
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
|
|
|
memset(&pi, 0, sizeof(pi));
|
|
|
|
DIE_IF_FALSE(
|
|
CreateProcess(
|
|
0 // exe name
|
|
,cmdbuf // command line
|
|
,0 // process security attributes
|
|
,0 // primary thread security attributes
|
|
,TRUE // handles are inherited
|
|
,0 // creation flags
|
|
,0 // use parent's environment
|
|
,0 // use parent's current directory
|
|
,&si // STARTUPINFO pointer
|
|
,&pi // receives PROCESS_INFORMATION
|
|
)
|
|
);
|
|
|
|
if ( ghJob != NULL )
|
|
if ( AssignProcessToJobObject(ghJob, pi.hProcess) == 0 ) {
|
|
fprintf(stderr, "Could not AssignProcessToObject\n");
|
|
}
|
|
|
|
// Do not handle Ctrl-C in the wrapper
|
|
SetConsoleCtrlHandler(NULL, TRUE);
|
|
|
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
|
|
|
DIE_IF_FALSE(
|
|
GetExitCodeProcess(pi.hProcess, &exitCode)
|
|
);
|
|
|
|
if ( ghJob != NULL )
|
|
CloseHandle(ghJob);
|
|
CloseHandle( pi.hProcess );
|
|
CloseHandle( pi.hThread );
|
|
|
|
free(envbuf);
|
|
free(resbuf);
|
|
free(cmdbuf);
|
|
|
|
dbg_printf("exiting with exitCode %d", exitCode);
|
|
|
|
return exitCode;
|
|
}
|