diff -Naur Python-2.7.9-orig/PC/getpathp.c Python-2.7.9/PC/getpathp.c --- Python-2.7.9-orig/PC/getpathp.c 2014-12-11 13:49:49.891400000 +0300 +++ Python-2.7.9/PC/getpathp.c 2014-12-11 13:49:59.579000000 +0300 @@ -98,10 +98,17 @@ # define USE_POSIX_PREFIX +# ifdef Py_ENABLE_SHARED +# define USE_EXEC_PREFIX +# endif + #endif static char prefix[MAXPATHLEN+1]; +#ifdef USE_EXEC_PREFIX +static char exec_prefix[MAXPATHLEN+1]; +#endif static char progpath[MAXPATHLEN+1]; static char dllpath[MAXPATHLEN+1]; static char *module_search_path = NULL; @@ -285,6 +292,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(char *argv0_path, char *home, char *_exec_prefix) +{ + size_t n; + + /* If PYTHONHOME is set, we believe it unconditionally */ + if (home) { + char *delim; + delim = srtchr(home, DELIM); + if (delim) + strncpy(exec_prefix, delim+1, MAXPATHLEN); + else + strncpy(exec_prefix, home, MAXPATHLEN); + join(exec_prefix, lib_python); + join(exec_prefix, "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. */ + strcpy(exec_prefix, argv0_path); + join(exec_prefix, "pybuilddir.txt"); + if (exists(exec_prefix)) { + FILE *f = _Py_fopen(exec_prefix, "rb"); + if (f == NULL) + errno = 0; + else { + char buf[MAXPATHLEN+1]; + PyObject *decoded; + char 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'; + strcpy(exec_prefix, argv0_path); + join(exec_prefix, rel_builddir_path); + return -1; + } + } + } + } + + /* Search from argv0_path, until root is found */ + strcpy(exec_prefix, argv0_path); + do { + n = strlen(exec_prefix); + join(exec_prefix, lib_python); + join(exec_prefix, "lib-dynload"); + if (exists(exec_prefix)) + return 1; + exec_prefix[n] = '\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. @@ -549,6 +632,9 @@ #ifdef USE_POSIX_PREFIX int pfound; #endif +#ifdef USE_EXEC_PREFIX + int efound; +#endif #ifdef MS_WINDOWS int skiphome, skipdefault; @@ -586,6 +672,16 @@ if (envpath && *envpath == '\0') envpath = NULL; +#ifdef USE_EXEC_PREFIX + efound = search_for_exec_prefix(argv0_path, pythonhome, NULL); + if (!efound) { + strncpy(exec_prefix, argv0_path, MAXPATHLEN); + reduce(exec_prefix); + join(exec_prefix, lib_python); + join(exec_prefix, "lib-dynload"); + } +#endif + #ifdef MS_WINDOWS /* Calculate zip archive path */ if (dllpath[0]) /* use name of python DLL */ @@ -642,6 +738,9 @@ #ifdef USE_POSIX_PREFIX bufsz += strlen(prefix) + 1; #endif +#ifdef USE_EXEC_PREFIX + bufsz +=strlen(exec_prefix) + 1; +#endif bufsz += strlen(PYTHONPATH) + 1; bufsz += strlen(argv0_path) + 1; #ifdef MS_WINDOWS @@ -691,6 +790,11 @@ buf = strchr(buf, '\0'); *buf++ = DELIM; #endif +#ifdef USE_EXEC_PREFIX + strcpy(buf, exec_prefix); + buf = strchr(buf, L'\0'); + *buf++ = DELIM; +#endif if (userpath) { strcpy(buf, userpath); buf = strchr(buf, '\0'); @@ -758,6 +862,17 @@ reduce(prefix); reduce(prefix); } + else + strcpy(prefix, argv0_path); +#endif +#ifdef USE_EXEC_PREFIX + if (efound > 0) { + reduce(exec_prefix); + reduce(exec_prefix); + reduce(exec_prefix); + } + else + strcpy(exec_prefix, argv0_path); #endif if (*prefix=='\0') { char lookBuf[MAXPATHLEN+1]; @@ -809,7 +924,13 @@ char * Py_GetExecPrefix(void) { +#ifdef USE_EXEC_PREFIX + if (!module_search_path) + calculate_path(); + return exec_prefix; +#else return Py_GetPrefix(); +#endif } char *