Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ typedef struct {
wchar_t *module_search_path_env;
/* PYTHONHOME environment variable, see also Py_SetPythonHome(). */
wchar_t *home;
/* Program name, see also Py_GetProgramName() */
wchar_t *program_name;
} _PyMainInterpreterConfig;

#define _PyMainInterpreterConfig_INIT \
Expand Down
60 changes: 32 additions & 28 deletions Modules/getpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ extern "C" {
typedef struct {
wchar_t prefix[MAXPATHLEN+1];
wchar_t exec_prefix[MAXPATHLEN+1];
wchar_t progpath[MAXPATHLEN+1];
wchar_t program_name[MAXPATHLEN+1];
wchar_t *module_search_path;
} PyPathConfig;

Expand All @@ -121,7 +121,7 @@ typedef struct {
wchar_t *home; /* PYTHONHOME environment variable */
wchar_t *module_search_path_env; /* PYTHONPATH environment variable */

wchar_t *prog; /* Program name */
wchar_t *program_name; /* Program name */
wchar_t *pythonpath; /* PYTHONPATH define */
wchar_t *prefix; /* PREFIX define */
wchar_t *exec_prefix; /* EXEC_PREFIX define */
Expand Down Expand Up @@ -602,8 +602,8 @@ calculate_progpath(PyCalculatePath *calculate, PyPathConfig *config)
* other way to find a directory to start the search from. If
* $PATH isn't exported, you lose.
*/
if (wcschr(calculate->prog, SEP)) {
wcsncpy(config->progpath, calculate->prog, MAXPATHLEN);
if (wcschr(calculate->program_name, SEP)) {
wcsncpy(config->program_name, calculate->program_name, MAXPATHLEN);
}
#ifdef __APPLE__
/* On Mac OS X, if a script uses an interpreter of the form
Expand All @@ -616,11 +616,13 @@ calculate_progpath(PyCalculatePath *calculate, PyPathConfig *config)
* 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 r = mbstowcs(config->progpath, execpath, MAXPATHLEN+1);
else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
execpath[0] == SEP)
{
size_t r = mbstowcs(config->program_name, execpath, MAXPATHLEN+1);
if (r == (size_t)-1 || r > MAXPATHLEN) {
/* Could not convert execpath, or it's too long. */
config->progpath[0] = '\0';
config->program_name[0] = '\0';
}
}
#endif /* __APPLE__ */
Expand All @@ -634,38 +636,38 @@ calculate_progpath(PyCalculatePath *calculate, PyPathConfig *config)
if (len > MAXPATHLEN) {
len = MAXPATHLEN;
}
wcsncpy(config->progpath, path, len);
*(config->progpath + len) = '\0';
wcsncpy(config->program_name, path, len);
*(config->program_name + len) = '\0';
}
else {
wcsncpy(config->progpath, path, MAXPATHLEN);
wcsncpy(config->program_name, path, MAXPATHLEN);
}

joinpath(config->progpath, calculate->prog);
if (isxfile(config->progpath)) {
joinpath(config->program_name, calculate->program_name);
if (isxfile(config->program_name)) {
break;
}

if (!delim) {
config->progpath[0] = L'\0';
config->program_name[0] = L'\0';
break;
}
path = delim + 1;
}
}
else {
config->progpath[0] = '\0';
config->program_name[0] = '\0';
}
if (config->progpath[0] != SEP && config->progpath[0] != '\0') {
absolutize(config->progpath);
if (config->program_name[0] != SEP && config->program_name[0] != '\0') {
absolutize(config->program_name);
}
}


static void
calculate_argv0_path(PyCalculatePath *calculate, PyPathConfig *config)
{
wcsncpy(calculate->argv0_path, config->progpath, MAXPATHLEN);
wcsncpy(calculate->argv0_path, config->program_name, MAXPATHLEN);
calculate->argv0_path[MAXPATHLEN] = '\0';

#ifdef WITH_NEXT_FRAMEWORK
Expand Down Expand Up @@ -700,10 +702,10 @@ calculate_argv0_path(PyCalculatePath *calculate, PyPathConfig *config)
if (!ismodule(calculate->argv0_path)) {
/* We are in the build directory so use the name of the
executable - we know that the absolute path is passed */
wcsncpy(calculate->argv0_path, config->progpath, MAXPATHLEN);
wcsncpy(calculate->argv0_path, config->program_name, MAXPATHLEN);
}
else {
/* Use the location of the library as the progpath */
/* Use the location of the library as the program_name */
wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
}
PyMem_RawFree(wbuf);
Expand All @@ -712,15 +714,15 @@ calculate_argv0_path(PyCalculatePath *calculate, PyPathConfig *config)

#if HAVE_READLINK
wchar_t tmpbuffer[MAXPATHLEN+1];
int linklen = _Py_wreadlink(config->progpath, tmpbuffer, MAXPATHLEN);
int linklen = _Py_wreadlink(config->program_name, tmpbuffer, MAXPATHLEN);
while (linklen != -1) {
if (tmpbuffer[0] == SEP) {
/* tmpbuffer should never be longer than MAXPATHLEN,
but extra check does not hurt */
wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
}
else {
/* Interpret relative to progpath */
/* Interpret relative to program_name */
reduce(calculate->argv0_path);
joinpath(calculate->argv0_path, tmpbuffer);
}
Expand Down Expand Up @@ -897,6 +899,7 @@ calculate_init(PyCalculatePath *calculate,
{
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");
Expand All @@ -907,8 +910,6 @@ calculate_init(PyCalculatePath *calculate,
}
}

calculate->prog = Py_GetProgramName();

calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
if (!calculate->pythonpath) {
return DECODE_LOCALE_ERR("PYTHONPATH define", len);
Expand Down Expand Up @@ -950,7 +951,9 @@ calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config)
calculate_zip_path(calculate, config);
calculate_exec_prefix(calculate, config);

if ((!calculate->prefix_found || !calculate->exec_prefix_found) && !Py_FrozenFlag) {
if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
!Py_FrozenFlag)
{
fprintf(stderr,
"Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
}
Expand Down Expand Up @@ -1018,10 +1021,11 @@ Py_SetPath(const wchar_t *path)
return;
}

wchar_t *prog = Py_GetProgramName();
wcsncpy(path_config.progpath, prog, MAXPATHLEN);
wchar_t *program_name = Py_GetProgramName();
wcsncpy(path_config.program_name, program_name, MAXPATHLEN);
path_config.exec_prefix[0] = path_config.prefix[0] = L'\0';
path_config.module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
size_t size = (wcslen(path) + 1) * sizeof(wchar_t);
path_config.module_search_path = PyMem_RawMalloc(size);
if (path_config.module_search_path != NULL) {
wcscpy(path_config.module_search_path, path);
}
Expand Down Expand Up @@ -1074,7 +1078,7 @@ Py_GetProgramFullPath(void)
if (!path_config.module_search_path) {
calculate_path(NULL);
}
return path_config.progpath;
return path_config.program_name;
}

#ifdef __cplusplus
Expand Down
21 changes: 16 additions & 5 deletions Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1452,6 +1452,13 @@ _PyMainInterpreterConfig_ReadEnv(_PyMainInterpreterConfig *config)
return err;
}

/* FIXME: _PyMainInterpreterConfig_Read() has the same code. Remove it
here? See also pymain_get_program_name() and pymain_parse_envvars(). */
config->program_name = _PyMem_RawWcsdup(Py_GetProgramName());
if (config->program_name == NULL) {
return _Py_INIT_NO_MEMORY();
}

return _Py_INIT_OK();
}

Expand Down Expand Up @@ -1480,6 +1487,15 @@ pymain_parse_envvars(_PyMain *pymain)
}
core_config->allocator = Py_GETENV("PYTHONMALLOC");

/* FIXME: move pymain_get_program_name() code into
_PyMainInterpreterConfig_ReadEnv().
Problem: _PyMainInterpreterConfig_ReadEnv() doesn't have access
to argv[0]. */
Py_SetProgramName(pymain->program_name);
/* Don't free program_name here: the argument to Py_SetProgramName
must remain valid until Py_FinalizeEx is called. The string is freed
by pymain_free(). */

_PyInitError err = _PyMainInterpreterConfig_ReadEnv(&pymain->config);
if (_Py_INIT_FAILED(pymain->err)) {
pymain->err = err;
Expand Down Expand Up @@ -1569,11 +1585,6 @@ pymain_init_python(_PyMain *pymain)
return -1;
}

Py_SetProgramName(pymain->program_name);
/* Don't free program_name here: the argument to Py_SetProgramName
must remain valid until Py_FinalizeEx is called. The string is freed
by pymain_free(). */

if (pymain_add_xoptions(pymain)) {
return -1;
}
Expand Down
61 changes: 28 additions & 33 deletions PC/getpathp.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@

typedef struct {
wchar_t prefix[MAXPATHLEN+1];
wchar_t progpath[MAXPATHLEN+1];
wchar_t program_name[MAXPATHLEN+1];
wchar_t dllpath[MAXPATHLEN+1];
wchar_t *module_search_path;
} PyPathConfig;
Expand All @@ -132,7 +132,7 @@ typedef struct {
wchar_t *machine_path; /* from HKEY_LOCAL_MACHINE */
wchar_t *user_path; /* from HKEY_CURRENT_USER */

wchar_t *prog; /* Program name */
wchar_t *program_name; /* Program name */
wchar_t argv0_path[MAXPATHLEN+1];
wchar_t zip_path[MAXPATHLEN+1];
} PyCalculatePath;
Expand Down Expand Up @@ -484,22 +484,22 @@ getpythonregpath(HKEY keyBase, int skipcore)


static void
get_progpath(PyCalculatePath *calculate, wchar_t *progpath, wchar_t *dllpath)
get_progpath(PyCalculatePath *calculate, PyPathConfig *config)
{
wchar_t *path = calculate->path_env;

#ifdef Py_ENABLE_SHARED
extern HANDLE PyWin_DLLhModule;
/* static init of progpath ensures final char remains \0 */
/* static init of program_name ensures final char remains \0 */
if (PyWin_DLLhModule) {
if (!GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) {
dllpath[0] = 0;
if (!GetModuleFileNameW(PyWin_DLLhModule, config->dllpath, MAXPATHLEN)) {
config->dllpath[0] = 0;
}
}
#else
dllpath[0] = 0;
config->dllpath[0] = 0;
#endif
if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN)) {
if (GetModuleFileNameW(NULL, config->program_name, MAXPATHLEN)) {
return;
}

Expand All @@ -509,12 +509,12 @@ get_progpath(PyCalculatePath *calculate, wchar_t *progpath, wchar_t *dllpath)
* $PATH isn't exported, you lose.
*/
#ifdef ALTSEP
if (wcschr(calculate->prog, SEP) || wcschr(calculate->prog, ALTSEP))
if (wcschr(calculate->program_name, SEP) || wcschr(calculate->program_name, ALTSEP))
#else
if (wcschr(calculate->prog, SEP))
if (wcschr(calculate->program_name, SEP))
#endif
{
wcsncpy(progpath, calculate->prog, MAXPATHLEN);
wcsncpy(config->program_name, calculate->program_name, MAXPATHLEN);
}
else if (path) {
while (1) {
Expand All @@ -524,28 +524,28 @@ get_progpath(PyCalculatePath *calculate, wchar_t *progpath, wchar_t *dllpath)
size_t len = delim - path;
/* ensure we can't overwrite buffer */
len = min(MAXPATHLEN,len);
wcsncpy(progpath, path, len);
*(progpath + len) = '\0';
wcsncpy(config->program_name, path, len);
*(config->program_name + len) = '\0';
}
else {
wcsncpy(progpath, path, MAXPATHLEN);
wcsncpy(config->program_name, path, MAXPATHLEN);
}

/* join() is safe for MAXPATHLEN+1 size buffer */
join(progpath, calculate->prog);
if (exists(progpath)) {
join(config->program_name, calculate->program_name);
if (exists(config->program_name)) {
break;
}

if (!delim) {
progpath[0] = '\0';
config->program_name[0] = '\0';
break;
}
path = delim + 1;
}
}
else {
progpath[0] = '\0';
config->program_name[0] = '\0';
}
}

Expand Down Expand Up @@ -695,14 +695,9 @@ calculate_init(PyCalculatePath *calculate,
{
calculate->home = main_config->home;
calculate->module_search_path_env = main_config->module_search_path_env;
calculate->program_name = main_config->program_name;

calculate->path_env = _wgetenv(L"PATH");

wchar_t *prog = Py_GetProgramName();
if (prog == NULL || *prog == '\0') {
prog = L"python";
}
calculate->prog = prog;
}


Expand All @@ -714,8 +709,8 @@ get_pth_filename(wchar_t *spbuffer, PyPathConfig *config)
return 1;
}
}
if (config->progpath[0]) {
if (!change_ext(spbuffer, config->progpath, L"._pth") && exists(spbuffer)) {
if (config->program_name[0]) {
if (!change_ext(spbuffer, config->program_name, L"._pth") && exists(spbuffer)) {
return 1;
}
}
Expand Down Expand Up @@ -784,9 +779,9 @@ static void
calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config,
const _PyMainInterpreterConfig *main_config)
{
get_progpath(calculate, config->progpath, config->dllpath);
/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, config->progpath);
get_progpath(calculate, config);
/* program_name guaranteed \0 terminated in MAXPATH+1 bytes. */
wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, config->program_name);
reduce(calculate->argv0_path);

/* Search for a sys.path file */
Expand All @@ -798,7 +793,7 @@ calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config,

/* Calculate zip archive path from DLL or exe path */
change_ext(calculate->zip_path,
config->dllpath[0] ? config->dllpath : config->progpath,
config->dllpath[0] ? config->dllpath : config->program_name,
L".zip");

if (calculate->home == NULL || *calculate->home == '\0') {
Expand Down Expand Up @@ -1057,8 +1052,8 @@ Py_SetPath(const wchar_t *path)
return;
}

wchar_t *prog = Py_GetProgramName();
wcsncpy(path_config.progpath, prog, MAXPATHLEN);
wchar_t *program_name = Py_GetProgramName();
wcsncpy(path_config.program_name, program_name, MAXPATHLEN);
path_config.prefix[0] = L'\0';
path_config.module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
if (path_config.module_search_path != NULL) {
Expand Down Expand Up @@ -1110,7 +1105,7 @@ Py_GetProgramFullPath(void)
if (!path_config.module_search_path) {
calculate_path(NULL);
}
return path_config.progpath;
return path_config.program_name;
}


Expand Down
Loading