summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-03-19 15:09:27 (GMT)
committerGitHub <noreply@github.com>2019-03-19 15:09:27 (GMT)
commitdcf617152e1d4c4a5e7965733928858a9c0936ca (patch)
tree61c2ce7f9a4bcb8a1f48efb1a24b0f50d4029372 /Python
parentf5f336a819a3d881bb217bf8f9b5cacba03a4e45 (diff)
downloadcpython-dcf617152e1d4c4a5e7965733928858a9c0936ca.zip
cpython-dcf617152e1d4c4a5e7965733928858a9c0936ca.tar.gz
cpython-dcf617152e1d4c4a5e7965733928858a9c0936ca.tar.bz2
bpo-36236: Handle removed cwd at Python init (GH-12424)
At Python initialization, the current directory is no longer prepended to sys.path if it has been removed. Rename _PyPathConfig_ComputeArgv0() to _PyPathConfig_ComputeSysPath0() to avoid confusion between argv[0] and sys.path[0].
Diffstat (limited to 'Python')
-rw-r--r--Python/pathconfig.c31
-rw-r--r--Python/sysmodule.c22
2 files changed, 35 insertions, 18 deletions
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
index f1818eb..743e1cd 100644
--- a/Python/pathconfig.c
+++ b/Python/pathconfig.c
@@ -566,9 +566,18 @@ Py_GetProgramName(void)
return _Py_path_config.program_name;
}
-/* Compute argv[0] which will be prepended to sys.argv */
-PyObject*
-_PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
+/* Compute module search path from argv[0] or the current working
+ directory ("-m module" case) which will be prepended to sys.argv:
+ sys.path[0].
+
+ Return 1 if the path is correctly resolved, but *path0_p can be NULL
+ if the Unicode object fail to be created.
+
+ Return 0 if it fails to resolve the full path (and *path0_p will be NULL),
+ for example if the current working directory has been removed (bpo-36236).
+ */
+int
+_PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p)
{
assert(_PyWstrList_CheckConsistency(argv));
@@ -588,6 +597,8 @@ _PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
wchar_t fullpath[MAX_PATH];
#endif
+ assert(*path0_p == NULL);
+
if (argv->length > 0) {
argv0 = argv->items[0];
have_module_arg = (wcscmp(argv0, L"-m") == 0);
@@ -595,14 +606,17 @@ _PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
}
if (have_module_arg) {
- #if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
- _Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath));
+#if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
+ if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) {
+ *path0_p = NULL;
+ return 0;
+ }
argv0 = fullpath;
n = wcslen(argv0);
- #else
+#else
argv0 = L".";
n = 1;
- #endif
+#endif
}
#ifdef HAVE_READLINK
@@ -675,7 +689,8 @@ _PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
}
#endif /* All others */
- return PyUnicode_FromWideChar(argv0, n);
+ *path0_p = PyUnicode_FromWideChar(argv0, n);
+ return 1;
}
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index b3330a01..4351a7f 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -2781,19 +2781,21 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
/* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
If argv[0] is a symlink, use the real path. */
const _PyWstrList argv_list = {.length = argc, .items = argv};
- PyObject *argv0 = _PyPathConfig_ComputeArgv0(&argv_list);
- if (argv0 == NULL) {
- Py_FatalError("can't compute path0 from argv");
- }
+ PyObject *path0 = NULL;
+ if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
+ if (path0 == NULL) {
+ Py_FatalError("can't compute path0 from argv");
+ }
- PyObject *sys_path = _PySys_GetObjectId(&PyId_path);
- if (sys_path != NULL) {
- if (PyList_Insert(sys_path, 0, argv0) < 0) {
- Py_DECREF(argv0);
- Py_FatalError("can't prepend path0 to sys.path");
+ PyObject *sys_path = _PySys_GetObjectId(&PyId_path);
+ if (sys_path != NULL) {
+ if (PyList_Insert(sys_path, 0, path0) < 0) {
+ Py_DECREF(path0);
+ Py_FatalError("can't prepend path0 to sys.path");
+ }
}
+ Py_DECREF(path0);
}
- Py_DECREF(argv0);
}
}