diff -Naur Python-3.5.0-orig/PC/getpathp.c Python-3.5.0/PC/getpathp.c --- Python-3.5.0-orig/PC/getpathp.c 2015-09-21 13:41:19.698879500 +0300 +++ Python-3.5.0/PC/getpathp.c 2015-09-21 13:41:30.111838100 +0300 @@ -104,10 +104,17 @@ # define USE_POSIX_PREFIX +# ifdef Py_ENABLE_SHARED +# define USE_EXEC_PREFIX +# endif + #endif static wchar_t prefix[MAXPATHLEN+1]; +#ifdef USE_EXEC_PREFIX +static wchar_t exec_prefix[MAXPATHLEN+1]; +#endif static wchar_t progpath[MAXPATHLEN+1]; static wchar_t dllpath[MAXPATHLEN+1]; static wchar_t *module_search_path = NULL; @@ -299,6 +306,82 @@ /* a string loaded from the DLL at startup.*/ extern const char *PyWin_DLLVersionString; +#ifdef USE_EXEC_PREFIX + +/* based on getpath.c but with path relative to executabe */ +/* search_for exec_prefix requires that paths be no more than + MAXPATHLEN bytes long. + return: 1 if found; -1 if found build directory +*/ +static int +search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix) +{ + size_t n; + + /* If PYTHONHOME is set, we believe it unconditionally */ + if (home) { + wchar_t *delim; + delim = wcschr(home, DELIM); + if (delim) + wcsncpy(exec_prefix, delim+1, MAXPATHLEN); + else + wcsncpy(exec_prefix, home, MAXPATHLEN); + join(exec_prefix, lib_python); + join(exec_prefix, L"lib-dynload"); + return 1; + } + + /* Check to see if argv[0] is in the build directory. "pybuilddir.txt" + is written by setup.py and contains the relative path to the location + of shared library modules. */ + wcscpy(exec_prefix, argv0_path); + join(exec_prefix, L"pybuilddir.txt"); + if (exists(exec_prefix)) { + FILE *f = _Py_wfopen(exec_prefix, L"rb"); + if (f == NULL) + errno = 0; + else { + char buf[MAXPATHLEN+1]; + PyObject *decoded; + wchar_t rel_builddir_path[MAXPATHLEN+1]; + n = fread(buf, 1, MAXPATHLEN, f); + buf[n] = '\0'; + fclose(f); + decoded = PyUnicode_DecodeMBCS(buf, n, NULL); + if (decoded != NULL) { + Py_ssize_t k; + k = PyUnicode_AsWideChar(decoded, + rel_builddir_path, MAXPATHLEN); + Py_DECREF(decoded); + if (k >= 0) { + rel_builddir_path[k] = L'\0'; + wcscpy(exec_prefix, argv0_path); + join(exec_prefix, rel_builddir_path); + return -1; + } + } + } + } + + /* Search from argv0_path, until root is found */ + wcscpy(exec_prefix, argv0_path); + do { + n = wcslen(exec_prefix); + join(exec_prefix, lib_python); + join(exec_prefix, L"lib-dynload"); + if (exists(exec_prefix)) + return 1; + exec_prefix[n] = L'\0'; + reduce(exec_prefix); + } while (exec_prefix[0]); + + /* Configure exec_prefix is unused */ + (void)_exec_prefix; + + /* Fail */ + return 0; +} +#endif /*def USE_EXEC_PREFIX*/ /* Load a PYTHONPATH value from the registry. Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER. @@ -570,6 +653,9 @@ #ifdef USE_POSIX_PREFIX int pfound; #endif +#ifdef USE_EXEC_PREFIX + int efound; +#endif #ifdef MS_WINDOWS int skiphome, skipdefault; @@ -665,6 +751,16 @@ if (envpath && *envpath == '\0') envpath = NULL; +#ifdef USE_EXEC_PREFIX + efound = search_for_exec_prefix(argv0_path, pythonhome, NULL); + if (!efound) { + wcsncpy(exec_prefix, argv0_path, MAXPATHLEN); + reduce(exec_prefix); + join(exec_prefix, lib_python); + join(exec_prefix, L"lib-dynload"); + } +#endif + #ifdef MS_WINDOWS /* Calculate zip archive path from DLL or exe path */ if (wcscpy_s(zip_path, MAXPATHLEN+1, dllpath[0] ? dllpath : progpath)) @@ -719,6 +815,9 @@ #ifdef USE_POSIX_PREFIX bufsz += wcslen(prefix) + 1; #endif +#ifdef USE_EXEC_PREFIX + bufsz += wcslen(exec_prefix) + 1; +#endif bufsz += wcslen(PYTHONPATH) + 1; bufsz += wcslen(argv0_path) + 1; #ifdef MS_WINDOWS @@ -768,6 +867,11 @@ buf = wcschr(buf, L'\0'); *buf++ = DELIM; #endif +#ifdef USE_EXEC_PREFIX + wcscpy(buf, exec_prefix); + buf = wcschr(buf, L'\0'); + *buf++ = DELIM; +#endif if (userpath) { if (wcscpy_s(buf, bufsz - (buf - module_search_path), userpath)) Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); @@ -841,6 +945,17 @@ reduce(prefix); reduce(prefix); } + else + wcscpy(prefix, argv0_path); +#endif +#ifdef USE_EXEC_PREFIX + if (efound > 0) { + reduce(exec_prefix); + reduce(exec_prefix); + reduce(exec_prefix); + } + else + wcscpy(exec_prefix, argv0_path); #endif if (*prefix==L'\0') { wchar_t lookBuf[MAXPATHLEN+1]; @@ -910,7 +1025,13 @@ wchar_t * Py_GetExecPrefix(void) { +#ifdef USE_EXEC_PREFIX + if (!module_search_path) + calculate_path(); + return exec_prefix; +#else return Py_GetPrefix(); +#endif } wchar_t *