]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-32030: Add _PyMainInterpreterConfig.program_name (#4548)
authorVictor Stinner <victor.stinner@gmail.com>
Fri, 24 Nov 2017 23:01:23 +0000 (00:01 +0100)
committerGitHub <noreply@github.com>
Fri, 24 Nov 2017 23:01:23 +0000 (00:01 +0100)
* Py_Main() now calls Py_SetProgramName() earlier to be able to get
  the program name in _PyMainInterpreterConfig_ReadEnv().
* Rename prog to program_name
* Rename progpath to program_name

Include/pystate.h
Modules/getpath.c
Modules/main.c
PC/getpathp.c
Python/pylifecycle.c

index 533851fc0283aff9b756512e29922993bfd204ac..60d001c4926c20ddcce9bde0381933d7cc0339c5 100644 (file)
@@ -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 \
index db28eaf66df2bc1e68b35051396f786cb2edffd0..9078aa81b3278dee74b09e88060c1fe3955b1086 100644 (file)
@@ -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;
 
@@ -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 */
@@ -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
@@ -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__ */
@@ -634,30 +636,30 @@ 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);
     }
 }
 
@@ -665,7 +667,7 @@ calculate_progpath(PyCalculatePath *calculate, PyPathConfig *config)
 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
@@ -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);
@@ -712,7 +714,7 @@ 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,
@@ -720,7 +722,7 @@ calculate_argv0_path(PyCalculatePath *calculate, PyPathConfig *config)
             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);
         }
@@ -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");
@@ -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);
@@ -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");
     }
@@ -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);
     }
@@ -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
index 5b0c04938411e6f8a57e83fd4acb5f435cc26838..dca165dad2c41aedb611ca95b70360ddacc004f3 100644 (file)
@@ -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();
 }
 
@@ -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;
@@ -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;
     }
index 5adf16d6f27384d76684b7a7038e1d3e5b482705..38e433b6dcd05aa0fbe2e456d5aa653d00b88faa 100644 (file)
 
 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;
@@ -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;
@@ -484,22 +484,22 @@ done:
 
 
 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;
     }
 
@@ -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) {
@@ -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';
     }
 }
 
@@ -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;
 }
 
 
@@ -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;
         }
     }
@@ -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 */
@@ -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') {
@@ -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) {
@@ -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;
 }
 
 
index e36b6c1b05718010a69a098bb6ac9b4358af17d5..714be3768f6ba36a26ce51446b37dd6f60ac6d9f 100644 (file)
@@ -802,6 +802,14 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config)
     if (config->install_signal_handlers < 0) {
         config->install_signal_handlers = 1;
     }
+
+    if (config->program_name == NULL) {
+        config->program_name = _PyMem_RawWcsdup(Py_GetProgramName());
+        if (config->program_name == NULL) {
+            return _Py_INIT_NO_MEMORY();
+        }
+    }
+
     return _Py_INIT_OK();
 }
 
@@ -809,10 +817,16 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config)
 void
 _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
 {
-    PyMem_RawFree(config->module_search_path_env);
-    config->module_search_path_env = NULL;
-    PyMem_RawFree(config->home);
-    config->home = NULL;
+#define CLEAR(ATTR) \
+    do { \
+        PyMem_RawFree(ATTR); \
+        ATTR = NULL; \
+    } while (0)
+
+    CLEAR(config->module_search_path_env);
+    CLEAR(config->home);
+    CLEAR(config->program_name);
+#undef CLEAR
 }