diff options
Diffstat (limited to 'PC/launcher.c')
| -rw-r--r-- | PC/launcher.c | 82 |
1 files changed, 56 insertions, 26 deletions
diff --git a/PC/launcher.c b/PC/launcher.c index 445e96e573..90a87b1c26 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Vinay Sajip. + * Copyright (C) 2011-2013 Vinay Sajip. * Licensed to PSF under a contributor agreement. * * Based on the work of: @@ -18,7 +18,7 @@ /* Build options. */ #define SKIP_PREFIX -/* #define SEARCH_PATH */ +#define SEARCH_PATH /* Just for now - static definition */ @@ -550,7 +550,7 @@ run_child(wchar_t * cmdline) error(RC_CREATE_PROCESS, L"Unable to create process using '%s'", cmdline); AssignProcessToJobObject(job, pi.hProcess); CloseHandle(pi.hThread); - WaitForSingleObject(pi.hProcess, INFINITE); + WaitForSingleObjectEx(pi.hProcess, INFINITE, FALSE); ok = GetExitCodeProcess(pi.hProcess, &rc); if (!ok) error(RC_CREATE_PROCESS, L"Failed to get exit code of process"); @@ -595,12 +595,17 @@ invoke_child(wchar_t * executable, wchar_t * suffix, wchar_t * cmdline) } } -static wchar_t * builtin_virtual_paths [] = { - L"/usr/bin/env python", - L"/usr/bin/python", - L"/usr/local/bin/python", - L"python", - NULL +typedef struct { + wchar_t *shebang; + BOOL search; +} SHEBANG; + +static SHEBANG builtin_virtual_paths [] = { + { L"/usr/bin/env python", TRUE }, + { L"/usr/bin/python", FALSE }, + { L"/usr/local/bin/python", FALSE }, + { L"python", FALSE }, + { NULL, FALSE }, }; /* For now, a static array of commands. */ @@ -776,10 +781,10 @@ static void read_commands() static BOOL parse_shebang(wchar_t * shebang_line, int nchars, wchar_t ** command, - wchar_t ** suffix) + wchar_t ** suffix, BOOL *search) { BOOL rc = FALSE; - wchar_t ** vpp; + SHEBANG * vpp; size_t plen; wchar_t * p; wchar_t zapped; @@ -789,15 +794,17 @@ parse_shebang(wchar_t * shebang_line, int nchars, wchar_t ** command, *command = NULL; /* failure return */ *suffix = NULL; + *search = FALSE; if ((*shebang_line++ == L'#') && (*shebang_line++ == L'!')) { shebang_line = skip_whitespace(shebang_line); if (*shebang_line) { *command = shebang_line; - for (vpp = builtin_virtual_paths; *vpp; ++vpp) { - plen = wcslen(*vpp); - if (wcsncmp(shebang_line, *vpp, plen) == 0) { + for (vpp = builtin_virtual_paths; vpp->shebang; ++vpp) { + plen = wcslen(vpp->shebang); + if (wcsncmp(shebang_line, vpp->shebang, plen) == 0) { rc = TRUE; + *search = vpp->search; /* We can do this because all builtin commands contain * "python". */ @@ -805,7 +812,7 @@ parse_shebang(wchar_t * shebang_line, int nchars, wchar_t ** command, break; } } - if (*vpp == NULL) { + if (vpp->shebang == NULL) { /* * Not found in builtins - look in customised commands. * @@ -1012,8 +1019,10 @@ maybe_handle_shebang(wchar_t ** argv, wchar_t * cmdline) int i, j, nchars = 0; int header_len; BOOL is_virt; + BOOL search; wchar_t * command; wchar_t * suffix; + COMMAND *cmd = NULL; INSTALLED_PYTHON * ip; if (rc == 0) { @@ -1125,7 +1134,7 @@ of bytes: %d\n", header_len); if (nchars > 0) { shebang_line[--nchars] = L'\0'; is_virt = parse_shebang(shebang_line, nchars, &command, - &suffix); + &suffix, &search); if (command != NULL) { debug(L"parse_shebang: found command: %s\n", command); if (!is_virt) { @@ -1141,6 +1150,23 @@ of bytes: %d\n", header_len); error(RC_BAD_VIRTUAL_PATH, L"Unknown virtual \ path '%s'", command); command += 6; /* skip past "python" */ + if (search && ((*command == L'\0') || isspace(*command))) { + /* Command is eligible for path search, and there + * is no version specification. + */ + debug(L"searching PATH for python executable\n"); + cmd = find_on_path(L"python"); + debug(L"Python on path: %s\n", cmd ? cmd->value : L"<not found>"); + if (cmd) { + debug(L"located python on PATH: %s\n", cmd->value); + invoke_child(cmd->value, suffix, cmdline); + /* Exit here, as we have found the command */ + return; + } + /* FALL THROUGH: No python found on PATH, so fall + * back to locating the correct installed python. + */ + } if (*command && !validate_version(command)) error(RC_BAD_VIRTUAL_PATH, L"Invalid version \ specification: '%s'.\nIn the first line of the script, 'python' needs to be \ @@ -1223,6 +1249,7 @@ process(int argc, wchar_t ** argv) void * version_data; VS_FIXEDFILEINFO * file_info; UINT block_size; + int index; wp = get_env(L"PYLAUNCH_DEBUG"); if ((wp != NULL) && (*wp != L'\0')) @@ -1271,8 +1298,8 @@ process(int argc, wchar_t ** argv) if (!valid) debug(L"GetFileVersionInfo failed: %X\n", GetLastError()); else { - valid = VerQueryValueW(version_data, L"\\", &file_info, - &block_size); + valid = VerQueryValueW(version_data, L"\\", + (LPVOID *) &file_info, &block_size); if (!valid) debug(L"VerQueryValue failed: %X\n", GetLastError()); else { @@ -1310,13 +1337,6 @@ process(int argc, wchar_t ** argv) else { p = argv[1]; plen = wcslen(p); - if (p[0] != L'-') { - read_commands(); - maybe_handle_shebang(&argv[1], command); - } - /* No file with shebang, or an unrecognised shebang. - * Is the first arg a special version qualifier? - */ valid = (*p == L'-') && validate_version(&p[1]); if (valid) { ip = locate_python(&p[1]); @@ -1326,6 +1346,16 @@ installed", &p[1]); command += wcslen(p); command = skip_whitespace(command); } + else { + for (index = 1; index < argc; ++index) { + if (*argv[index] != L'-') + break; + } + if (index < argc) { + read_commands(); + maybe_handle_shebang(&argv[index], command); + } + } } if (!valid) { ip = locate_python(L""); @@ -1344,7 +1374,7 @@ installed", &p[1]); fwprintf(stdout, L"\ Python Launcher for Windows Version %s\n\n", version_text); fwprintf(stdout, L"\ -usage: %s [ launcher-arguments ] script [ script-arguments ]\n\n", argv[0]); +usage: %s [ launcher-arguments ] [ python-arguments ] script [ script-arguments ]\n\n", argv[0]); fputws(L"\ Launcher arguments:\n\n\ -2 : Launch the latest Python 2.x version\n\ |
