static _PyInitError calculate_path_impl(const _PyCoreConfig *core_config, PyCalculatePath *calculate, _PyPathConfig *config) { _PyInitError err; err = calculate_program_full_path(core_config, calculate, config); if (_Py_INIT_FAILED(err)) { return err; } err = calculate_argv0_path(calculate, config->program_full_path); if (_Py_INIT_FAILED(err)) { return err; } calculate_read_pyenv(calculate); wchar_t prefix[MAXPATHLEN+1]; memset(prefix, 0, sizeof(prefix)); calculate_prefix(core_config, calculate, prefix); calculate_zip_path(calculate, prefix); wchar_t exec_prefix[MAXPATHLEN+1]; memset(exec_prefix, 0, sizeof(exec_prefix)); calculate_exec_prefix(core_config, calculate, exec_prefix); if ((!calculate->prefix_found || !calculate->exec_prefix_found) && !core_config->_frozen) { fprintf(stderr, "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); } err = calculate_module_search_path(core_config, calculate, prefix, exec_prefix, config); if (_Py_INIT_FAILED(err)) { return err; } calculate_reduce_prefix(calculate, prefix); config->prefix = _PyMem_RawWcsdup(prefix); if (config->prefix == NULL) { return _Py_INIT_NO_MEMORY(); } calculate_reduce_exec_prefix(calculate, exec_prefix); config->exec_prefix = _PyMem_RawWcsdup(exec_prefix); if (config->exec_prefix == NULL) { return _Py_INIT_NO_MEMORY(); } return _Py_INIT_OK(); }
static _PyInitError canonicalize(wchar_t *buffer, const wchar_t *path) { if (buffer == NULL) { return _Py_INIT_NO_MEMORY(); } if (_PathCchCanonicalizeEx_Initialized == 0) { HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll"); if (pathapi) { _PathCchCanonicalizeEx = (PPathCchCanonicalizeEx)GetProcAddress(pathapi, "PathCchCanonicalizeEx"); } else { _PathCchCanonicalizeEx = NULL; } _PathCchCanonicalizeEx_Initialized = 1; } if (_PathCchCanonicalizeEx) { if (FAILED(_PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, 0))) { return _Py_INIT_ERR("buffer overflow in getpathp.c's canonicalize()"); } } else { if (!PathCanonicalizeW(buffer, path)) { return _Py_INIT_ERR("buffer overflow in getpathp.c's canonicalize()"); } } return _Py_INIT_OK(); }
/* Set the global path configuration from core_config. */ _PyInitError _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config) { PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyInitError err; _PyPathConfig path_config = _PyPathConfig_INIT; path_config.module_search_path = wstrlist_join(DELIM, core_config->nmodule_search_path, core_config->module_search_paths); if (path_config.module_search_path == NULL) { goto no_memory; } if (copy_wstr(&path_config.program_full_path, core_config->executable) < 0) { goto no_memory; } if (copy_wstr(&path_config.prefix, core_config->prefix) < 0) { goto no_memory; } #ifdef MS_WINDOWS if (copy_wstr(&path_config.dll_path, core_config->dll_path) < 0) { goto no_memory; } #else if (copy_wstr(&path_config.exec_prefix, core_config->exec_prefix) < 0) { goto no_memory; } #endif if (copy_wstr(&path_config.program_name, core_config->program_name) < 0) { goto no_memory; } if (copy_wstr(&path_config.home, core_config->home) < 0) { goto no_memory; } err = _PyPathConfig_SetGlobal(&path_config); if (_Py_INIT_FAILED(err)) { goto done; } err = _Py_INIT_OK(); goto done; no_memory: err = _Py_INIT_NO_MEMORY(); done: _PyPathConfig_Clear(&path_config); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return err; }
/* Calculate the path configuration: initialize path_config from core_config */ static _PyInitError _PyPathConfig_Calculate(_PyPathConfig *path_config, const _PyCoreConfig *core_config) { _PyInitError err; _PyPathConfig new_config = _PyPathConfig_INIT; PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); /* Calculate program_full_path, prefix, exec_prefix (Unix) or dll_path (Windows), and module_search_path */ err = _PyPathConfig_Calculate_impl(&new_config, core_config); if (_Py_INIT_FAILED(err)) { goto err; } /* Copy home and program_name from core_config */ if (copy_wstr(&new_config.home, core_config->home) < 0) { err = _Py_INIT_NO_MEMORY(); goto err; } if (copy_wstr(&new_config.program_name, core_config->program_name) < 0) { err = _Py_INIT_NO_MEMORY(); goto err; } _PyPathConfig_Clear(path_config); *path_config = new_config; err = _Py_INIT_OK(); goto done; err: _PyPathConfig_Clear(&new_config); done: PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return err; }
static _PyInitError calculate_path_impl(const _PyCoreConfig *core_config, PyCalculatePath *calculate, _PyPathConfig *config) { _PyInitError err; err = get_dll_path(calculate, config); if (_Py_INIT_FAILED(err)) { return err; } err = get_program_full_path(core_config, calculate, config); if (_Py_INIT_FAILED(err)) { return err; } /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */ wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, config->program_full_path); reduce(calculate->argv0_path); wchar_t prefix[MAXPATHLEN+1]; memset(prefix, 0, sizeof(prefix)); /* Search for a sys.path file */ if (calculate_pth_file(config, prefix)) { goto done; } calculate_pyvenv_file(calculate); /* Calculate zip archive path from DLL or exe path */ change_ext(calculate->zip_path, config->dll_path[0] ? config->dll_path : config->program_full_path, L".zip"); calculate_home_prefix(calculate, prefix); err = calculate_module_search_path(core_config, calculate, config, prefix); if (_Py_INIT_FAILED(err)) { return err; } done: config->prefix = _PyMem_RawWcsdup(prefix); if (config->prefix == NULL) { return _Py_INIT_NO_MEMORY(); } return _Py_INIT_OK(); }
static _PyInitError core_config_init_module_search_paths(_PyCoreConfig *config, _PyPathConfig *path_config) { assert(config->module_search_paths == NULL); assert(config->nmodule_search_path < 0); config->nmodule_search_path = 0; const wchar_t *sys_path = path_config->module_search_path; const wchar_t delim = DELIM; const wchar_t *p = sys_path; while (1) { p = wcschr(sys_path, delim); if (p == NULL) { p = sys_path + wcslen(sys_path); /* End of string */ } size_t path_len = (p - sys_path); wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t)); if (path == NULL) { return _Py_INIT_NO_MEMORY(); } memcpy(path, sys_path, path_len * sizeof(wchar_t)); path[path_len] = L'\0'; _PyInitError err = _Py_wstrlist_append(&config->nmodule_search_path, &config->module_search_paths, path); PyMem_RawFree(path); if (_Py_INIT_FAILED(err)) { return err; } if (*p == '\0') { break; } sys_path = p + 1; } return _Py_INIT_OK(); }
static _PyInitError get_dll_path(PyCalculatePath *calculate, _PyPathConfig *config) { 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)) { dll_path[0] = 0; } } #else dll_path[0] = 0; #endif config->dll_path = _PyMem_RawWcsdup(dll_path); if (config->dll_path == NULL) { return _Py_INIT_NO_MEMORY(); } return _Py_INIT_OK(); }
static _PyInitError calculate_module_search_path(const _PyCoreConfig *core_config, PyCalculatePath *calculate, const wchar_t *prefix, const wchar_t *exec_prefix, _PyPathConfig *config) { /* Calculate size of return buffer */ size_t bufsz = 0; if (core_config->module_search_path_env != NULL) { bufsz += wcslen(core_config->module_search_path_env) + 1; } wchar_t *defpath = calculate->pythonpath; size_t prefixsz = wcslen(prefix) + 1; while (1) { wchar_t *delim = wcschr(defpath, DELIM); if (defpath[0] != SEP) { /* Paths are relative to prefix */ bufsz += prefixsz; } if (delim) { bufsz += delim - defpath + 1; } else { bufsz += wcslen(defpath) + 1; break; } defpath = delim + 1; } bufsz += wcslen(calculate->zip_path) + 1; bufsz += wcslen(exec_prefix) + 1; /* Allocate the buffer */ wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t)); if (buf == NULL) { return _Py_INIT_NO_MEMORY(); } buf[0] = '\0'; /* Run-time value of $PYTHONPATH goes first */ if (core_config->module_search_path_env) { wcscpy(buf, core_config->module_search_path_env); wcscat(buf, delimiter); } /* Next is the default zip path */ wcscat(buf, calculate->zip_path); wcscat(buf, delimiter); /* Next goes merge of compile-time $PYTHONPATH with * dynamically located prefix. */ defpath = calculate->pythonpath; while (1) { wchar_t *delim = wcschr(defpath, DELIM); if (defpath[0] != SEP) { wcscat(buf, prefix); if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP && defpath[0] != (delim ? DELIM : L'\0')) { /* not empty */ wcscat(buf, separator); } } if (delim) { size_t len = delim - defpath + 1; size_t end = wcslen(buf) + len; wcsncat(buf, defpath, len); buf[end] = '\0'; } else { wcscat(buf, defpath); break; } defpath = delim + 1; } wcscat(buf, delimiter); /* Finally, on goes the directory for dynamic-load modules */ wcscat(buf, exec_prefix); config->module_search_path = buf; return _Py_INIT_OK(); }
static _PyInitError calculate_program_full_path(const _PyCoreConfig *core_config, PyCalculatePath *calculate, _PyPathConfig *config) { wchar_t program_full_path[MAXPATHLEN+1]; memset(program_full_path, 0, sizeof(program_full_path)); #ifdef __APPLE__ #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 uint32_t nsexeclength = MAXPATHLEN; #else unsigned long nsexeclength = MAXPATHLEN; #endif char execpath[MAXPATHLEN+1]; #endif /* If there is no slash in the argv0 path, then we have to * assume python is on the user's $PATH, since there's no * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ if (wcschr(core_config->program_name, SEP)) { wcsncpy(program_full_path, core_config->program_name, MAXPATHLEN); } #ifdef __APPLE__ /* On Mac OS X, if a script uses an interpreter of the form * "#!/opt/python2.3/bin/python", the kernel only passes "python" * as argv[0], which falls through to the $PATH search below. * If /opt/python2.3/bin isn't in your path, or is near the end, * this algorithm may incorrectly find /usr/bin/python. To work * around this, we can use _NSGetExecutablePath to get a better * hint of what the intended interpreter was, although this * will fail if a relative path was used. but in that case, * absolutize() should help us out below */ else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && execpath[0] == SEP) { size_t len; wchar_t *path = Py_DecodeLocale(execpath, &len); if (path == NULL) { return DECODE_LOCALE_ERR("executable path", len); } wcsncpy(program_full_path, path, MAXPATHLEN); PyMem_RawFree(path); } #endif /* __APPLE__ */ else if (calculate->path_env) { wchar_t *path = calculate->path_env; while (1) { wchar_t *delim = wcschr(path, DELIM); if (delim) { size_t len = delim - path; if (len > MAXPATHLEN) { len = MAXPATHLEN; } wcsncpy(program_full_path, path, len); program_full_path[len] = '\0'; } else { wcsncpy(program_full_path, path, MAXPATHLEN); } joinpath(program_full_path, core_config->program_name); if (isxfile(program_full_path)) { break; } if (!delim) { program_full_path[0] = L'\0'; break; } path = delim + 1; } } else { program_full_path[0] = '\0'; } if (program_full_path[0] != SEP && program_full_path[0] != '\0') { absolutize(program_full_path); } config->program_full_path = _PyMem_RawWcsdup(program_full_path); if (config->program_full_path == NULL) { return _Py_INIT_NO_MEMORY(); } return _Py_INIT_OK(); }
_PyInitError _PyCoreConfig_InitPathConfig(_PyCoreConfig *config) { _PyPathConfig path_config = _PyPathConfig_INIT; _PyInitError err; err = _PyPathConfig_Calculate(&path_config, config); if (_Py_INIT_FAILED(err)) { goto error; } if (config->nmodule_search_path < 0) { err = core_config_init_module_search_paths(config, &path_config); if (_Py_INIT_FAILED(err)) { goto error; } } if (config->executable == NULL) { if (copy_wstr(&config->executable, path_config.program_full_path) < 0) { goto no_memory; } } if (config->prefix == NULL) { if (copy_wstr(&config->prefix, path_config.prefix) < 0) { goto no_memory; } } if (config->exec_prefix == NULL) { #ifdef MS_WINDOWS wchar_t *exec_prefix = path_config.prefix; #else wchar_t *exec_prefix = path_config.exec_prefix; #endif if (copy_wstr(&config->exec_prefix, exec_prefix) < 0) { goto no_memory; } } #ifdef MS_WINDOWS if (config->dll_path == NULL) { if (copy_wstr(&config->dll_path, path_config.dll_path) < 0) { goto no_memory; } } #endif if (config->base_prefix == NULL) { if (copy_wstr(&config->base_prefix, config->prefix) < 0) { goto no_memory; } } if (config->base_exec_prefix == NULL) { if (copy_wstr(&config->base_exec_prefix, config->exec_prefix) < 0) { goto no_memory; } } if (path_config.isolated != -1) { config->isolated = path_config.isolated; } if (path_config.site_import != -1) { config->site_import = path_config.site_import; } _PyPathConfig_Clear(&path_config); return _Py_INIT_OK(); no_memory: err = _Py_INIT_NO_MEMORY(); error: _PyPathConfig_Clear(&path_config); return err; }