bpo-32030: Cleanup "path config" code (#4663)

* Rename PyPathConfig structure to _PyPathConfig and move it to
  Include/internal/pystate.h
* Rename path_config to _Py_path_config
* _PyPathConfig: Rename program_name field to program_full_path
* Add assert(str != NULL); to _PyMem_RawWcsdup(), _PyMem_RawStrdup()
  and _PyMem_Strdup().
* Rename calculate_path() to pathconfig_global_init(). The function
  now does nothing if it's already initiallized.
This commit is contained in:
Victor Stinner 2017-12-01 18:27:09 +01:00 committed by GitHub
parent 8f5c28b193
commit b64de46aae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 136 additions and 137 deletions

View file

@ -80,6 +80,7 @@
#include "Python.h"
#include "internal/pystate.h"
#include "osdefs.h"
#include <wchar.h>
@ -116,13 +117,6 @@
#define LANDMARK L"lib\\os.py"
#endif
typedef struct {
wchar_t *prefix;
wchar_t *program_name;
wchar_t *dll_path;
wchar_t *module_search_path;
} PyPathConfig;
typedef struct {
wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
wchar_t *path_env; /* PATH environment variable */
@ -138,7 +132,7 @@ typedef struct {
} PyCalculatePath;
static PyPathConfig path_config = {.module_search_path = NULL};
static _PyPathConfig _Py_path_config = _PyPathConfig_INIT;
/* determine if "ch" is a separator character */
@ -295,7 +289,7 @@ gotlandmark(wchar_t *prefix, const wchar_t *landmark)
/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
assumption provided by only caller, calculate_path() */
assumption provided by only caller, calculate_path_impl() */
static int
search_for_prefix(wchar_t *prefix, wchar_t *argv0_path, const wchar_t *landmark)
{
@ -484,7 +478,7 @@ done:
static _PyInitError
get_dll_path(PyCalculatePath *calculate, PyPathConfig *config)
get_dll_path(PyCalculatePath *calculate, _PyPathConfig *config)
{
wchar_t dll_path[MAXPATHLEN+1];
memset(dll_path, 0, sizeof(dll_path));
@ -509,12 +503,12 @@ get_dll_path(PyCalculatePath *calculate, PyPathConfig *config)
static _PyInitError
get_program_name(PyCalculatePath *calculate, PyPathConfig *config)
get_program_full_path(PyCalculatePath *calculate, _PyPathConfig *config)
{
wchar_t program_name[MAXPATHLEN+1];
memset(program_name, 0, sizeof(program_name));
wchar_t program_full_path[MAXPATHLEN+1];
memset(program_full_path, 0, sizeof(program_full_path));
if (GetModuleFileNameW(NULL, program_name, MAXPATHLEN)) {
if (GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) {
goto done;
}
@ -529,7 +523,7 @@ get_program_name(PyCalculatePath *calculate, PyPathConfig *config)
if (wcschr(calculate->program_name, SEP))
#endif
{
wcsncpy(program_name, calculate->program_name, MAXPATHLEN);
wcsncpy(program_full_path, calculate->program_name, MAXPATHLEN);
}
else if (calculate->path_env) {
wchar_t *path = calculate->path_env;
@ -540,33 +534,33 @@ get_program_name(PyCalculatePath *calculate, PyPathConfig *config)
size_t len = delim - path;
/* ensure we can't overwrite buffer */
len = min(MAXPATHLEN,len);
wcsncpy(program_name, path, len);
program_name[len] = '\0';
wcsncpy(program_full_path, path, len);
program_full_path[len] = '\0';
}
else {
wcsncpy(program_name, path, MAXPATHLEN);
wcsncpy(program_full_path, path, MAXPATHLEN);
}
/* join() is safe for MAXPATHLEN+1 size buffer */
join(program_name, calculate->program_name);
if (exists(program_name)) {
join(program_full_path, calculate->program_name);
if (exists(program_full_path)) {
break;
}
if (!delim) {
program_name[0] = '\0';
program_full_path[0] = '\0';
break;
}
path = delim + 1;
}
}
else {
program_name[0] = '\0';
program_full_path[0] = '\0';
}
done:
config->program_name = _PyMem_RawWcsdup(program_name);
if (config->program_name == NULL) {
config->program_full_path = _PyMem_RawWcsdup(program_full_path);
if (config->program_full_path == NULL) {
return _Py_INIT_NO_MEMORY();
}
return _Py_INIT_OK();
@ -626,7 +620,7 @@ find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
static int
read_pth_file(PyPathConfig *config, wchar_t *prefix, const wchar_t *path,
read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path,
int *isolated, int *nosite)
{
FILE *sp_file = _Py_wfopen(path, L"r");
@ -727,15 +721,15 @@ calculate_init(PyCalculatePath *calculate,
static int
get_pth_filename(wchar_t *spbuffer, PyPathConfig *config)
get_pth_filename(wchar_t *spbuffer, _PyPathConfig *config)
{
if (config->dll_path[0]) {
if (!change_ext(spbuffer, config->dll_path, L"._pth") && exists(spbuffer)) {
return 1;
}
}
if (config->program_name[0]) {
if (!change_ext(spbuffer, config->program_name, L"._pth") && exists(spbuffer)) {
if (config->program_full_path[0]) {
if (!change_ext(spbuffer, config->program_full_path, L"._pth") && exists(spbuffer)) {
return 1;
}
}
@ -744,7 +738,7 @@ get_pth_filename(wchar_t *spbuffer, PyPathConfig *config)
static int
calculate_pth_file(PyPathConfig *config, wchar_t *prefix)
calculate_pth_file(_PyPathConfig *config, wchar_t *prefix)
{
wchar_t spbuffer[MAXPATHLEN+1];
@ -821,7 +815,7 @@ calculate_home_prefix(PyCalculatePath *calculate, wchar_t *prefix)
static _PyInitError
calculate_module_search_path(PyCalculatePath *calculate, PyPathConfig *config, wchar_t *prefix)
calculate_module_search_path(PyCalculatePath *calculate, _PyPathConfig *config, wchar_t *prefix)
{
int skiphome = calculate->home==NULL ? 0 : 1;
#ifdef Py_ENABLE_SHARED
@ -1002,7 +996,7 @@ calculate_module_search_path(PyCalculatePath *calculate, PyPathConfig *config, w
static _PyInitError
calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config,
calculate_path_impl(PyCalculatePath *calculate, _PyPathConfig *config,
const _PyMainInterpreterConfig *main_config)
{
_PyInitError err;
@ -1012,13 +1006,13 @@ calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config,
return err;
}
err = get_program_name(calculate, config);
err = get_program_full_path(calculate, config);
if (_Py_INIT_FAILED(err)) {
return err;
}
/* program_name guaranteed \0 terminated in MAXPATH+1 bytes. */
wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, config->program_name);
/* 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];
@ -1033,7 +1027,7 @@ calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config,
/* Calculate zip archive path from DLL or exe path */
change_ext(calculate->zip_path,
config->dll_path[0] ? config->dll_path : config->program_name,
config->dll_path[0] ? config->dll_path : config->program_full_path,
L".zip");
calculate_home_prefix(calculate, prefix);
@ -1062,7 +1056,7 @@ calculate_free(PyCalculatePath *calculate)
static void
pathconfig_clear(PyPathConfig *config)
pathconfig_clear(_PyPathConfig *config)
{
#define CLEAR(ATTR) \
do { \
@ -1071,7 +1065,7 @@ pathconfig_clear(PyPathConfig *config)
} while (0)
CLEAR(config->prefix);
CLEAR(config->program_name);
CLEAR(config->program_full_path);
CLEAR(config->dll_path);
CLEAR(config->module_search_path);
#undef CLEAR
@ -1083,7 +1077,7 @@ pathconfig_clear(PyPathConfig *config)
_PyInitError
_PyPathConfig_Init(const _PyMainInterpreterConfig *main_config)
{
if (path_config.module_search_path) {
if (_Py_path_config.module_search_path) {
/* Already initialized */
return _Py_INIT_OK();
}
@ -1095,7 +1089,7 @@ _PyPathConfig_Init(const _PyMainInterpreterConfig *main_config)
calculate_init(&calculate, main_config);
PyPathConfig new_path_config;
_PyPathConfig new_path_config;
memset(&new_path_config, 0, sizeof(new_path_config));
err = calculate_path_impl(&calculate, &new_path_config, main_config);
@ -1103,7 +1097,7 @@ _PyPathConfig_Init(const _PyMainInterpreterConfig *main_config)
goto done;
}
path_config = new_path_config;
_Py_path_config = new_path_config;
err = _Py_INIT_OK();
done:
@ -1116,8 +1110,13 @@ done:
static void
calculate_path(void)
pathconfig_global_init(void)
{
if (_Py_path_config.module_search_path) {
/* Already initialized */
return;
}
_PyInitError err;
_PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
@ -1136,7 +1135,7 @@ calculate_path(void)
void
_PyPathConfig_Fini(void)
{
pathconfig_clear(&path_config);
pathconfig_clear(&_Py_path_config);
}
@ -1145,42 +1144,38 @@ _PyPathConfig_Fini(void)
void
Py_SetPath(const wchar_t *path)
{
if (path_config.module_search_path != NULL) {
pathconfig_clear(&path_config);
if (_Py_path_config.module_search_path != NULL) {
pathconfig_clear(&_Py_path_config);
}
if (path == NULL) {
return;
}
PyPathConfig new_config;
new_config.program_name = _PyMem_RawWcsdup(Py_GetProgramName());
_PyPathConfig new_config;
new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName());
new_config.prefix = _PyMem_RawWcsdup(L"");
new_config.dll_path = _PyMem_RawWcsdup(L"");
new_config.module_search_path = _PyMem_RawWcsdup(path);
pathconfig_clear(&path_config);
path_config = new_config;
pathconfig_clear(&_Py_path_config);
_Py_path_config = new_config;
}
wchar_t *
Py_GetPath(void)
{
if (!path_config.module_search_path) {
calculate_path();
}
return path_config.module_search_path;
pathconfig_global_init();
return _Py_path_config.module_search_path;
}
wchar_t *
Py_GetPrefix(void)
{
if (!path_config.module_search_path) {
calculate_path();
}
return path_config.prefix;
pathconfig_global_init();
return _Py_path_config.prefix;
}
@ -1194,10 +1189,8 @@ Py_GetExecPrefix(void)
wchar_t *
Py_GetProgramFullPath(void)
{
if (!path_config.module_search_path) {
calculate_path();
}
return path_config.program_name;
pathconfig_global_init();
return _Py_path_config.program_full_path;
}
@ -1221,7 +1214,7 @@ _Py_CheckPython3()
/* If there is a python3.dll next to the python3y.dll,
assume this is a build tree; use that DLL */
wcscpy(py3path, path_config.dll_path);
wcscpy(py3path, _Py_path_config.dll_path);
s = wcsrchr(py3path, L'\\');
if (!s) {
s = py3path;