| diff -Naur Python-3.8.0-orig/Include/pylifecycle.h Python-3.8.0/Include/pylifecycle.h |
| --- Python-3.8.0-orig/Include/pylifecycle.h 2019-10-22 10:02:41.276120000 +0300 |
| +++ Python-3.8.0/Include/pylifecycle.h 2019-10-22 10:02:44.427325500 +0300 |
| @@ -53,7 +53,7 @@ |
| PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void); |
| PyAPI_FUNC(wchar_t *) Py_GetPath(void); |
| PyAPI_FUNC(void) Py_SetPath(const wchar_t *); |
| -#ifdef MS_WINDOWS |
| +#ifdef _MSC_VER |
| int _Py_CheckPython3(void); |
| #endif |
| |
| diff -Naur Python-3.8.0-orig/Modules/getpath.c Python-3.8.0/Modules/getpath.c |
| --- Python-3.8.0-orig/Modules/getpath.c 2019-10-14 16:34:47.000000000 +0300 |
| +++ Python-3.8.0/Modules/getpath.c 2019-10-22 10:02:44.848526300 +0300 |
| @@ -14,6 +14,11 @@ |
| # include <mach-o/dyld.h> |
| #endif |
| |
| +#ifdef MS_WINDOWS |
| +#include <windows.h> |
| +#include <shlwapi.h> |
| +#endif |
| + |
| /* Search in some common locations for the associated Python libraries. |
| * |
| * Two directories must be found, the platform independent directory |
| @@ -132,13 +137,39 @@ |
| int prefix_found; /* found platform independent libraries? */ |
| int exec_prefix_found; /* found the platform dependent libraries? */ |
| |
| + wchar_t *dll_path; |
| int warnings; |
| const wchar_t *pythonpath_env; |
| } PyCalculatePath; |
| |
| static const wchar_t delimiter[2] = {DELIM, '\0'}; |
| -static const wchar_t separator[2] = {SEP, '\0'}; |
| +static wchar_t separator[2] = {SEP, '\0'}; |
| |
| +static int |
| +is_sep(wchar_t ch) |
| +{ |
| +#ifdef _WIN32 |
| + return ch == SEP || ch == ALTSEP; |
| +#else |
| + return ch == SEP; |
| +#endif |
| +} |
| + |
| +static int |
| +is_absolute(const wchar_t *path) |
| +{ |
| +#ifdef _WIN32 |
| + size_t i = wcslen(path); |
| + if (i >= 3) { |
| + if (iswalpha(path[0]) && path[1] == L':' && is_sep(path[2])) { |
| + return 1; |
| + } |
| + } |
| + return 0; |
| +#else |
| + return path[0] == SEP; |
| +#endif |
| +} |
| |
| /* Get file status. Encode the path to the locale encoding. */ |
| static int |
| @@ -161,7 +192,7 @@ |
| reduce(wchar_t *dir) |
| { |
| size_t i = wcslen(dir); |
| - while (i > 0 && dir[i] != SEP) { |
| + while (i > 0 && !is_sep(dir[i])) { |
| --i; |
| } |
| dir[i] = '\0'; |
| @@ -241,14 +272,14 @@ |
| joinpath(wchar_t *buffer, const wchar_t *stuff, size_t buflen) |
| { |
| size_t n, k; |
| - if (stuff[0] != SEP) { |
| + if (!is_sep(stuff[0])) { |
| n = wcslen(buffer); |
| if (n >= buflen) { |
| return PATHLEN_ERR(); |
| } |
| |
| - if (n > 0 && buffer[n-1] != SEP) { |
| - buffer[n++] = SEP; |
| + if (n > 0 && !is_sep(buffer[n-1]) != SEP) { |
| + buffer[n++] = Py_GetSepW(buffer); |
| } |
| } |
| else { |
| @@ -284,7 +315,7 @@ |
| static PyStatus |
| copy_absolute(wchar_t *path, const wchar_t *p, size_t pathlen) |
| { |
| - if (p[0] == SEP) { |
| + if (is_absolute(p)) { |
| if (safe_wcscpy(path, p, pathlen) < 0) { |
| return PATHLEN_ERR(); |
| } |
| @@ -297,7 +328,7 @@ |
| } |
| return _PyStatus_OK(); |
| } |
| - if (p[0] == '.' && p[1] == SEP) { |
| + if (p[0] == '.' && is_sep(p[1])) { |
| p += 2; |
| } |
| PyStatus status = joinpath(path, p, pathlen); |
| @@ -313,7 +344,7 @@ |
| static PyStatus |
| absolutize(wchar_t *path, size_t path_len) |
| { |
| - if (path[0] == SEP) { |
| + if (is_absolute(path)) { |
| return _PyStatus_OK(); |
| } |
| |
| @@ -403,6 +434,7 @@ |
| return status; |
| } |
| |
| + Py_NormalizeSepsW(path); |
| if (isfile(path)) { |
| /* Check VPATH to see if argv0_path is in the build directory. |
| VPATH can be empty. */ |
| @@ -427,6 +459,7 @@ |
| return status; |
| } |
| |
| + Py_NormalizeSepsW(prefix); |
| if (ismodule(prefix, prefix_len)) { |
| *found = -1; |
| reduce(prefix); |
| @@ -529,12 +562,21 @@ |
| * return the compiled-in defaults instead. |
| */ |
| if (calculate->prefix_found > 0) { |
| +#ifdef _WIN32 |
| + wchar_t drive_root[3]; |
| + memset(drive_root, 0, sizeof(drive_root)); |
| + wcsncpy(drive_root, prefix, 3); |
| +#endif |
| reduce(prefix); |
| reduce(prefix); |
| /* The prefix is the root directory, but reduce() chopped |
| * off the "/". */ |
| if (!prefix[0]) { |
| +#ifdef _WIN32 |
| + wcsncpy(prefix, drive_root, 3); |
| +#else |
| wcscpy(prefix, separator); |
| +#endif |
| } |
| pathconfig->prefix = _PyMem_RawWcsdup(prefix); |
| } |
| @@ -649,6 +691,7 @@ |
| |
| /* Check for pybuilddir.txt */ |
| assert(*found == 0); |
| + Py_NormalizeSepsW(exec_prefix); |
| status = calculate_pybuilddir(argv0_path, exec_prefix, exec_prefix_len, |
| found); |
| if (_PyStatus_EXCEPTION(status)) { |
| @@ -734,6 +777,7 @@ |
| if (_PyStatus_EXCEPTION(status)) { |
| return status; |
| } |
| + Py_NormalizeSepsW(exec_prefix); |
| } |
| /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ |
| return _PyStatus_OK(); |
| @@ -746,11 +790,20 @@ |
| wchar_t *exec_prefix) |
| { |
| if (calculate->exec_prefix_found > 0) { |
| +#ifdef _WIN32 |
| + wchar_t drive_root[3]; |
| + memset(drive_root, 0, sizeof(drive_root)); |
| + wcsncpy(drive_root, exec_prefix, 3); |
| +#endif |
| reduce(exec_prefix); |
| reduce(exec_prefix); |
| reduce(exec_prefix); |
| if (!exec_prefix[0]) { |
| +#ifdef _WIN32 |
| + wcsncpy(exec_prefix, drive_root, 3); |
| +#else |
| wcscpy(exec_prefix, separator); |
| +#endif |
| } |
| |
| pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix); |
| @@ -767,6 +820,48 @@ |
| } |
| |
| |
| +#ifdef MS_WINDOWS |
| +static int |
| +GetWindowsModulePaths(wchar_t *progpath) |
| +{ |
| + int result = 0; |
| + wchar_t program_full_path[MAXPATHLEN+1]; |
| + memset(program_full_path, 0, sizeof(program_full_path)); |
| + |
| + if (GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) { |
| + result = 1; |
| + Py_NormalizeSepsW(program_full_path); |
| + } |
| + |
| + wcscpy(progpath, program_full_path); |
| + return result; |
| +} |
| + |
| + |
| +wchar_t* |
| +_Py_GetDLLPath(void) |
| +{ |
| + wchar_t dll_path[MAXPATHLEN+1]; |
| + memset(dll_path, 0, sizeof(dll_path)); |
| + |
| +#ifdef Py_ENABLE_SHARED |
| + extern HANDLE PyWin_DLLhModule; |
| + if (PyWin_DLLhModule) { |
| + if (GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) { |
| + Py_NormalizeSepsW(dll_path); |
| + } else { |
| + dll_path[0] = 0; |
| + } |
| + } |
| +#else |
| + dll_path[0] = 0; |
| +#endif |
| + |
| + return _PyMem_RawWcsdup(dll_path); |
| +} |
| +#endif /* MS_WINDOWS */ |
| + |
| + |
| static PyStatus |
| calculate_program_full_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) |
| { |
| @@ -789,7 +884,7 @@ |
| * other way to find a directory to start the search from. If |
| * $PATH isn't exported, you lose. |
| */ |
| - if (wcschr(pathconfig->program_name, SEP)) { |
| + if (wcschr(pathconfig->program_name, Py_GetSepW(pathconfig->program_name))) { |
| if (safe_wcscpy(program_full_path, pathconfig->program_name, |
| program_full_path_len) < 0) { |
| return PATHLEN_ERR(); |
| @@ -821,6 +916,10 @@ |
| PyMem_RawFree(path); |
| } |
| #endif /* __APPLE__ */ |
| +#ifdef MS_WINDOWS |
| + else if(GetWindowsModulePaths(program_full_path)) { |
| + } |
| +#endif /* MS_WINDOWS */ |
| else if (calculate->path_env) { |
| wchar_t *path = calculate->path_env; |
| while (1) { |
| @@ -861,7 +960,7 @@ |
| else { |
| program_full_path[0] = '\0'; |
| } |
| - if (program_full_path[0] != SEP && program_full_path[0] != '\0') { |
| + if (!is_absolute(program_full_path)) { |
| status = absolutize(program_full_path, program_full_path_len); |
| if (_PyStatus_EXCEPTION(status)) { |
| return status; |
| @@ -1071,6 +1170,7 @@ |
| if (_PyStatus_EXCEPTION(status)) { |
| return status; |
| } |
| + Py_NormalizeSepsW(zip_path); |
| |
| /* Replace "00" with version */ |
| size_t bufsz = wcslen(zip_path); |
| @@ -1098,7 +1198,7 @@ |
| while (1) { |
| wchar_t *delim = wcschr(defpath, DELIM); |
| |
| - if (defpath[0] != SEP) { |
| + if (!is_absolute(defpath)) { |
| /* Paths are relative to prefix */ |
| bufsz += prefixsz; |
| } |
| @@ -1115,6 +1215,11 @@ |
| |
| bufsz += wcslen(zip_path) + 1; |
| bufsz += wcslen(exec_prefix) + 1; |
| +#ifdef MS_WINDOWS |
| + if (is_absolute(prefix)) { |
| + bufsz += wcslen(prefix) + 1; |
| + } |
| +#endif |
| |
| /* Allocate the buffer */ |
| wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t)); |
| @@ -1140,9 +1245,9 @@ |
| while (1) { |
| wchar_t *delim = wcschr(defpath, DELIM); |
| |
| - if (defpath[0] != SEP) { |
| + if (!is_absolute(defpath)) { |
| wcscat(buf, prefix); |
| - if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP && |
| + if (prefixsz >= 2 && !is_sep(prefix[prefixsz - 2]) && |
| defpath[0] != (delim ? DELIM : L'\0')) |
| { |
| /* not empty */ |
| @@ -1163,6 +1268,12 @@ |
| defpath = delim + 1; |
| } |
| wcscat(buf, delimiter); |
| +#ifdef MS_WINDOWS |
| + if (is_absolute(prefix)) { |
| + wcscat(buf, prefix); |
| + wcscat(buf, delimiter); |
| + } |
| +#endif |
| |
| /* Finally, on goes the directory for dynamic-load modules */ |
| wcscat(buf, exec_prefix); |
| @@ -1188,16 +1299,20 @@ |
| if (!calculate->pythonpath) { |
| return DECODE_LOCALE_ERR("PYTHONPATH define", len); |
| } |
| + Py_NormalizeSepsW(calculate->pythonpath); |
| |
| calculate->prefix = Py_DecodeLocale(PREFIX, &len); |
| if (!calculate->prefix) { |
| return DECODE_LOCALE_ERR("PREFIX define", len); |
| } |
| + Py_NormalizeSepsW(calculate->prefix); |
| calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len); |
| if (!calculate->exec_prefix) { |
| return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); |
| } |
| - calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len); |
| + Py_NormalizeSepsW(calculate->exec_prefix); |
| + const char *lib_python_VERSION = (Py_GetSepW(NULL) == L'/') ? "lib/python" VERSION : "lib\\python" VERSION; |
| + calculate->lib_python = Py_DecodeLocale(lib_python_VERSION, &len); |
| if (!calculate->lib_python) { |
| return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); |
| } |
| @@ -1215,6 +1330,7 @@ |
| PyMem_RawFree(calculate->pythonpath); |
| PyMem_RawFree(calculate->prefix); |
| PyMem_RawFree(calculate->exec_prefix); |
| + PyMem_RawFree(calculate->dll_path); |
| PyMem_RawFree(calculate->lib_python); |
| PyMem_RawFree(calculate->path_env); |
| } |
| @@ -1225,6 +1341,8 @@ |
| { |
| PyStatus status; |
| |
| + calculate->dll_path = _Py_GetDLLPath(); |
| + |
| if (pathconfig->program_full_path == NULL) { |
| status = calculate_program_full_path(calculate, pathconfig); |
| if (_PyStatus_EXCEPTION(status)) { |
| @@ -1343,6 +1461,7 @@ |
| { |
| PyStatus status; |
| PyCalculatePath calculate; |
| + separator[0] = Py_GetSepW(NULL); |
| memset(&calculate, 0, sizeof(calculate)); |
| |
| status = calculate_init(&calculate, config); |
| diff -Naur Python-3.8.0-orig/Modules/posixmodule.c Python-3.8.0/Modules/posixmodule.c |
| --- Python-3.8.0-orig/Modules/posixmodule.c 2019-10-22 10:02:42.087321400 +0300 |
| +++ Python-3.8.0/Modules/posixmodule.c 2019-10-22 10:02:45.238527000 +0300 |
| @@ -3691,7 +3691,7 @@ |
| Py_END_ALLOW_THREADS |
| /* FindNextFile sets error to ERROR_NO_MORE_FILES if |
| it got to the end of the directory. */ |
| - if (!result && GetLastError() != ERROR_NO_MORE_FILES) { |
| + if (!result && GetLastError() != 0 && GetLastError() != ERROR_NO_MORE_FILES) { |
| Py_DECREF(list); |
| list = path_error(path); |
| goto exit; |
| diff -Naur Python-3.8.4-orig/Python/dynload_win.c Python-3.8.4/Python/dynload_win.c |
| --- Python-3.8.4-orig/Python/dynload_win.c 2019-10-22 10:01:24.710185500 +0300 |
| +++ Python-3.8.4/Python/dynload_win.c 2019-10-22 10:02:45.644127700 +0300 |
| @@ -180,7 +180,9 @@ |
| char funcname[258], *import_python; |
| const wchar_t *wpathname; |
| |
| +#if defined(_MSC_VER) |
| _Py_CheckPython3(); |
| +#endif |
| |
| wpathname = _PyUnicode_AsUnicode(pathname); |
| if (wpathname == NULL) |