summaryrefslogtreecommitdiffstats
path: root/Modules/getpath.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-12-02 19:36:00 (GMT)
committerGitHub <noreply@github.com>2017-12-02 19:36:00 (GMT)
commit13badcbc60cdbfae1dba1683fd2fae9d70717143 (patch)
tree08df481be4201aeb0c8875c115168d4c4e055140 /Modules/getpath.c
parentaf5a895073c24637c094772b27526b94a12ec897 (diff)
downloadcpython-13badcbc60cdbfae1dba1683fd2fae9d70717143.zip
cpython-13badcbc60cdbfae1dba1683fd2fae9d70717143.tar.gz
cpython-13badcbc60cdbfae1dba1683fd2fae9d70717143.tar.bz2
bpo-32197: Try to fix a compiler error on OS X introduced in bpo-32030. (#4681)
* Revert "bpo-32030: _PyPathConfig_Init() sets home and program_name (#4673)" This reverts commit af5a895073c24637c094772b27526b94a12ec897. * Revert "bpo-32030: Fix config_get_program_name() on macOS (#4669)" This reverts commit e23c06e2b03452c9aaf0dae52296c85e572f9bcd. * Revert "bpo-32030: Add Python/pathconfig.c (#4668)" This reverts commit 0ea395ae964c9cd0f499e2ef0d0030c971201220. * Revert "bpo-32030: Don't call _PyPathConfig_Fini() in Py_FinalizeEx() (#4667)" This reverts commit ebac19dad6263141d5db0a2c923efe049dba99d2. * Revert "bpo-32030: Fix Py_GetPath(): init program_name (#4665)" This reverts commit 9ac3d8882712c9675c3d2f9f84af6b5729575cde.
Diffstat (limited to 'Modules/getpath.c')
-rw-r--r--Modules/getpath.c197
1 files changed, 151 insertions, 46 deletions
diff --git a/Modules/getpath.c b/Modules/getpath.c
index fc2b544..9f5e8b3 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -117,7 +117,10 @@ extern "C" {
typedef struct {
wchar_t *path_env; /* PATH environment variable */
+ wchar_t *home; /* PYTHONHOME environment variable */
+ wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
+ wchar_t *program_name; /* Program name */
wchar_t *pythonpath; /* PYTHONPATH define */
wchar_t *prefix; /* PREFIX define */
wchar_t *exec_prefix; /* EXEC_PREFIX define */
@@ -132,6 +135,7 @@ typedef struct {
static const wchar_t delimiter[2] = {DELIM, '\0'};
static const wchar_t separator[2] = {SEP, '\0'};
+static _PyPathConfig _Py_path_config = _PyPathConfig_INIT;
/* Get file status. Encode the path to the locale encoding. */
@@ -356,15 +360,14 @@ find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
bytes long.
*/
static int
-search_for_prefix(const _PyMainInterpreterConfig *main_config,
- PyCalculatePath *calculate, wchar_t *prefix)
+search_for_prefix(PyCalculatePath *calculate, wchar_t *prefix)
{
size_t n;
wchar_t *vpath;
/* If PYTHONHOME is set, we believe it unconditionally */
- if (main_config->home) {
- wcsncpy(prefix, main_config->home, MAXPATHLEN);
+ if (calculate->home) {
+ wcsncpy(prefix, calculate->home, MAXPATHLEN);
prefix[MAXPATHLEN] = L'\0';
wchar_t *delim = wcschr(prefix, DELIM);
if (delim) {
@@ -423,10 +426,9 @@ search_for_prefix(const _PyMainInterpreterConfig *main_config,
static void
-calculate_prefix(const _PyMainInterpreterConfig *main_config,
- PyCalculatePath *calculate, wchar_t *prefix)
+calculate_prefix(PyCalculatePath *calculate, wchar_t *prefix)
{
- calculate->prefix_found = search_for_prefix(main_config, calculate, prefix);
+ calculate->prefix_found = search_for_prefix(calculate, prefix);
if (!calculate->prefix_found) {
if (!Py_FrozenFlag) {
fprintf(stderr,
@@ -468,19 +470,18 @@ calculate_reduce_prefix(PyCalculatePath *calculate, wchar_t *prefix)
MAXPATHLEN bytes long.
*/
static int
-search_for_exec_prefix(const _PyMainInterpreterConfig *main_config,
- PyCalculatePath *calculate, wchar_t *exec_prefix)
+search_for_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
{
size_t n;
/* If PYTHONHOME is set, we believe it unconditionally */
- if (main_config->home) {
- wchar_t *delim = wcschr(main_config->home, DELIM);
+ if (calculate->home) {
+ wchar_t *delim = wcschr(calculate->home, DELIM);
if (delim) {
wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
}
else {
- wcsncpy(exec_prefix, main_config->home, MAXPATHLEN);
+ wcsncpy(exec_prefix, calculate->home, MAXPATHLEN);
}
exec_prefix[MAXPATHLEN] = L'\0';
joinpath(exec_prefix, calculate->lib_python);
@@ -551,12 +552,9 @@ search_for_exec_prefix(const _PyMainInterpreterConfig *main_config,
static void
-calculate_exec_prefix(const _PyMainInterpreterConfig *main_config,
- PyCalculatePath *calculate, wchar_t *exec_prefix)
+calculate_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
{
- calculate->exec_prefix_found = search_for_exec_prefix(main_config,
- calculate,
- exec_prefix);
+ calculate->exec_prefix_found = search_for_exec_prefix(calculate, exec_prefix);
if (!calculate->exec_prefix_found) {
if (!Py_FrozenFlag) {
fprintf(stderr,
@@ -587,8 +585,7 @@ calculate_reduce_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
static _PyInitError
-calculate_program_full_path(const _PyMainInterpreterConfig *main_config,
- PyCalculatePath *calculate, _PyPathConfig *config)
+calculate_program_full_path(PyCalculatePath *calculate, _PyPathConfig *config)
{
wchar_t program_full_path[MAXPATHLEN+1];
memset(program_full_path, 0, sizeof(program_full_path));
@@ -607,8 +604,8 @@ calculate_program_full_path(const _PyMainInterpreterConfig *main_config,
* other way to find a directory to start the search from. If
* $PATH isn't exported, you lose.
*/
- if (wcschr(main_config->program_name, SEP)) {
- wcsncpy(program_full_path, main_config->program_name, MAXPATHLEN);
+ if (wcschr(calculate->program_name, SEP)) {
+ wcsncpy(program_full_path, calculate->program_name, MAXPATHLEN);
}
#ifdef __APPLE__
/* On Mac OS X, if a script uses an interpreter of the form
@@ -624,13 +621,11 @@ calculate_program_full_path(const _PyMainInterpreterConfig *main_config,
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);
+ size_t r = mbstowcs(program_full_path, execpath, MAXPATHLEN+1);
+ if (r == (size_t)-1 || r > MAXPATHLEN) {
+ /* Could not convert execpath, or it's too long. */
+ program_full_path[0] = '\0';
}
- wcsncpy(program_full_path, path, MAXPATHLEN);
- PyMem_RawFree(path);
}
#endif /* __APPLE__ */
else if (calculate->path_env) {
@@ -650,7 +645,7 @@ calculate_program_full_path(const _PyMainInterpreterConfig *main_config,
wcsncpy(program_full_path, path, MAXPATHLEN);
}
- joinpath(program_full_path, main_config->program_name);
+ joinpath(program_full_path, calculate->program_name);
if (isxfile(program_full_path)) {
break;
}
@@ -815,15 +810,14 @@ calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
static _PyInitError
-calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
- PyCalculatePath *calculate,
+calculate_module_search_path(PyCalculatePath *calculate,
const wchar_t *prefix, const wchar_t *exec_prefix,
_PyPathConfig *config)
{
/* Calculate size of return buffer */
size_t bufsz = 0;
- if (main_config->module_search_path_env != NULL) {
- bufsz += wcslen(main_config->module_search_path_env) + 1;
+ if (calculate->module_search_path_env != NULL) {
+ bufsz += wcslen(calculate->module_search_path_env) + 1;
}
wchar_t *defpath = calculate->pythonpath;
@@ -857,8 +851,8 @@ calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
buf[0] = '\0';
/* Run-time value of $PYTHONPATH goes first */
- if (main_config->module_search_path_env) {
- wcscpy(buf, main_config->module_search_path_env);
+ if (calculate->module_search_path_env) {
+ wcscpy(buf, calculate->module_search_path_env);
wcscat(buf, delimiter);
}
@@ -909,6 +903,10 @@ static _PyInitError
calculate_init(PyCalculatePath *calculate,
const _PyMainInterpreterConfig *main_config)
{
+ calculate->home = main_config->home;
+ calculate->module_search_path_env = main_config->module_search_path_env;
+ calculate->program_name = main_config->program_name;
+
size_t len;
char *path = getenv("PATH");
if (path) {
@@ -950,12 +948,9 @@ calculate_free(PyCalculatePath *calculate)
static _PyInitError
-calculate_path_impl(const _PyMainInterpreterConfig *main_config,
- PyCalculatePath *calculate, _PyPathConfig *config)
+calculate_path_impl(PyCalculatePath *calculate, _PyPathConfig *config)
{
- _PyInitError err;
-
- err = calculate_program_full_path(main_config, calculate, config);
+ _PyInitError err = calculate_program_full_path(calculate, config);
if (_Py_INIT_FAILED(err)) {
return err;
}
@@ -969,13 +964,13 @@ calculate_path_impl(const _PyMainInterpreterConfig *main_config,
wchar_t prefix[MAXPATHLEN+1];
memset(prefix, 0, sizeof(prefix));
- calculate_prefix(main_config, calculate, prefix);
+ calculate_prefix(calculate, prefix);
calculate_zip_path(calculate, prefix);
wchar_t exec_prefix[MAXPATHLEN+1];
memset(exec_prefix, 0, sizeof(exec_prefix));
- calculate_exec_prefix(main_config, calculate, exec_prefix);
+ calculate_exec_prefix(calculate, exec_prefix);
if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
!Py_FrozenFlag)
@@ -984,8 +979,8 @@ calculate_path_impl(const _PyMainInterpreterConfig *main_config,
"Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
}
- err = calculate_module_search_path(main_config, calculate,
- prefix, exec_prefix, config);
+ err = calculate_module_search_path(calculate, prefix, exec_prefix,
+ config);
if (_Py_INIT_FAILED(err)) {
return err;
}
@@ -1008,10 +1003,33 @@ calculate_path_impl(const _PyMainInterpreterConfig *main_config,
}
+static void
+pathconfig_clear(_PyPathConfig *config)
+{
+#define CLEAR(ATTR) \
+ do { \
+ PyMem_RawFree(ATTR); \
+ ATTR = NULL; \
+ } while (0)
+
+ CLEAR(config->prefix);
+ CLEAR(config->exec_prefix);
+ CLEAR(config->program_full_path);
+ CLEAR(config->module_search_path);
+#undef CLEAR
+}
+
+
+/* Initialize paths for Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix()
+ and Py_GetProgramFullPath() */
_PyInitError
-_PyPathConfig_Calculate(_PyPathConfig *config,
- const _PyMainInterpreterConfig *main_config)
+_PyPathConfig_Init(const _PyMainInterpreterConfig *main_config)
{
+ if (_Py_path_config.module_search_path) {
+ /* Already initialized */
+ return _Py_INIT_OK();
+ }
+
PyCalculatePath calculate;
memset(&calculate, 0, sizeof(calculate));
@@ -1020,11 +1038,16 @@ _PyPathConfig_Calculate(_PyPathConfig *config,
goto done;
}
- err = calculate_path_impl(main_config, &calculate, config);
+ _PyPathConfig new_path_config;
+ memset(&new_path_config, 0, sizeof(new_path_config));
+
+ err = calculate_path_impl(&calculate, &new_path_config);
if (_Py_INIT_FAILED(err)) {
+ pathconfig_clear(&new_path_config);
goto done;
}
+ _Py_path_config = new_path_config;
err = _Py_INIT_OK();
done:
@@ -1032,6 +1055,88 @@ done:
return err;
}
+
+static void
+pathconfig_global_init(void)
+{
+ if (_Py_path_config.module_search_path) {
+ /* Already initialized */
+ return;
+ }
+
+ _PyInitError err;
+ _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
+
+ err = _PyMainInterpreterConfig_ReadEnv(&config);
+ if (!_Py_INIT_FAILED(err)) {
+ err = _PyPathConfig_Init(&config);
+ }
+ _PyMainInterpreterConfig_Clear(&config);
+
+ if (_Py_INIT_FAILED(err)) {
+ _Py_FatalInitError(err);
+ }
+}
+
+
+void
+_PyPathConfig_Fini(void)
+{
+ pathconfig_clear(&_Py_path_config);
+}
+
+
+/* External interface */
+void
+Py_SetPath(const wchar_t *path)
+{
+ if (path == NULL) {
+ pathconfig_clear(&_Py_path_config);
+ return;
+ }
+
+ _PyPathConfig new_config;
+ new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName());
+ new_config.exec_prefix = _PyMem_RawWcsdup(L"");
+ new_config.prefix = _PyMem_RawWcsdup(L"");
+ new_config.module_search_path = _PyMem_RawWcsdup(path);
+
+ pathconfig_clear(&_Py_path_config);
+ _Py_path_config = new_config;
+}
+
+
+wchar_t *
+Py_GetPath(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.module_search_path;
+}
+
+
+wchar_t *
+Py_GetPrefix(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.prefix;
+}
+
+
+wchar_t *
+Py_GetExecPrefix(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.exec_prefix;
+}
+
+
+wchar_t *
+Py_GetProgramFullPath(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.program_full_path;
+}
+
#ifdef __cplusplus
}
#endif