diff options
author | guyroz <devnull@localhost> | 2011-09-17 16:25:22 +0300 |
---|---|---|
committer | guyroz <devnull@localhost> | 2011-09-17 16:25:22 +0300 |
commit | 20a7af621198102673b3d5c464375cd38480f9f7 (patch) | |
tree | 9356c5546857f47f2c0a50f5ce8f9445d268d2d0 /launcher.c | |
parent | 923d7c0294fdd3aab8a2e659da8e531d9c6f7f75 (diff) | |
download | python-setuptools-bitbucket-20a7af621198102673b3d5c464375cd38480f9f7.tar.gz |
Issue #207: passing ctrl-c events to python child process
Diffstat (limited to 'launcher.c')
-rwxr-xr-x | launcher.c | 102 |
1 files changed, 91 insertions, 11 deletions
@@ -25,9 +25,12 @@ #include <stdlib.h> #include <stdio.h> -#include <unistd.h> +#include <string.h> +#include <windows.h> +#include <tchar.h> #include <fcntl.h> -#include "windows.h" + +int child_pid=0; int fail(char *format, char *data) { /* Print error message to stderr and return 2 */ @@ -35,10 +38,6 @@ int fail(char *format, char *data) { return 2; } - - - - char *quoted(char *data) { int i, ln = strlen(data), nb; @@ -90,7 +89,7 @@ char *loadable_exe(char *exename) { /* Return the absolute filename for spawnv */ result = calloc(MAX_PATH, sizeof(char)); strncpy(result, exename, MAX_PATH); - /*if (result) GetModuleFileName(hPython, result, MAX_PATH); + /*if (result) GetModuleFileNameA(hPython, result, MAX_PATH); FreeLibrary(hPython); */ return result; @@ -160,8 +159,82 @@ char **parse_argv(char *cmdline, int *argc) } while (1); } +void pass_control_to_child(DWORD control_type) { + /* + * distribute-issue207 + * passes the control event to child process (Python) + */ + if (!child_pid) { + return; + } + GenerateConsoleCtrlEvent(child_pid,0); +} + +BOOL control_handler(DWORD control_type) { + /* + * distribute-issue207 + * control event handler callback function + */ + switch (control_type) { + case CTRL_C_EVENT: + pass_control_to_child(0); + break; + } + return TRUE; +} + +int create_and_wait_for_subprocess(char* command) { + /* + * distribute-issue207 + * launches child process (Python) + */ + DWORD return_value = 0; + LPSTR commandline = command; + STARTUPINFOA s_info; + PROCESS_INFORMATION p_info; + ZeroMemory(&p_info, sizeof(p_info)); + ZeroMemory(&s_info, sizeof(s_info)); + s_info.cb = sizeof(STARTUPINFO); + // set-up control handler callback funciotn + SetConsoleCtrlHandler((PHANDLER_ROUTINE) control_handler, TRUE); + if (!CreateProcessA(NULL, commandline, NULL, NULL, TRUE, 0, NULL, NULL, &s_info, &p_info)) { + fprintf(stderr, "failed to create process.\n"); + return 0; + } + child_pid = p_info.dwProcessId; + // wait for Python to exit + WaitForSingleObject(p_info.hProcess, INFINITE); + if (!GetExitCodeProcess(p_info.hProcess, &return_value)) { + fprintf(stderr, "failed to get exit code from process.\n"); + return 0; + } + return return_value; +} +char* join_executable_and_args(char *executable, char **args, int argc) +{ + /* + * distribute-issue207 + * CreateProcess needs a long string of the executable and command-line arguments, + * so we need to convert it from the args that was built + */ + int len,counter; + char* cmdline; + + len=strlen(executable)+2; + for (counter=1; counter<argc; counter++) { + len+=strlen(args[counter])+1; + } + cmdline = (char*)calloc(len, sizeof(char)); + sprintf(cmdline, "%s", executable); + len=strlen(executable); + for (counter=1; counter<argc; counter++) { + sprintf(cmdline+len, " %s", args[counter]); + len+=strlen(args[counter])+1; + } + return cmdline; +} int run(int argc, char **argv, int is_gui) { @@ -173,10 +246,11 @@ int run(int argc, char **argv, int is_gui) { char **newargs, **newargsp, **parsedargs; /* argument array for exec */ char *ptr, *end; /* working pointers for string manipulation */ + char *cmdline; int i, parsedargc; /* loop counter */ /* compute script name from our .exe name*/ - GetModuleFileName(NULL, script, sizeof(script)); + GetModuleFileNameA(NULL, script, sizeof(script)); end = script + strlen(script); while( end>script && *end != '.') *end-- = '\0'; @@ -236,12 +310,18 @@ int run(int argc, char **argv, int is_gui) { return fail("Could not exec %s", ptr); /* shouldn't get here! */ } - /* We *do* need to wait for a CLI to finish, so use spawn */ - return spawnv(P_WAIT, ptr, (const char * const *)(newargs)); + /* + * distribute-issue207: using CreateProcessA instead of spawnv + */ + cmdline = join_executable_and_args(ptr, newargs, parsedargc + argc); + return create_and_wait_for_subprocess(cmdline); } - int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR lpCmd, int nShow) { return run(__argc, __argv, GUI); } +int main(int argc, char** argv) { + return run(argc, argv, GUI); +} + |