summaryrefslogtreecommitdiff
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-01-21 19:25:32 +0100
committerGitHub <noreply@github.com>2020-01-21 19:25:32 +0100
commit623ed6171eae35af7fd2e804dfd9c832c05c5d48 (patch)
treef48cb78948e40705749cb10c734c7da844bdfb60 /Modules
parent56cd3710a1ea3ba872d345ea1bebc86ed08bc8b8 (diff)
downloadcpython-git-623ed6171eae35af7fd2e804dfd9c832c05c5d48.tar.gz
bpo-39406: Add PY_PUTENV_DICT macro to posixmodule.c (GH-18106)
Rename posix_putenv_garbage to putenv_dict.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/posixmodule.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index d2047d9c2a..5a0c8a311a 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -819,9 +819,19 @@ dir_fd_converter(PyObject *o, void *p)
}
}
+#ifdef HAVE_PUTENV
+# define PY_PUTENV_DICT
+#endif
+
typedef struct {
PyObject *billion;
- PyObject *posix_putenv_garbage;
+#ifdef PY_PUTENV_DICT
+ /* putenv() and _wputenv() requires that the caller manages the environment
+ variable memory. Use a Python dictionary for that: name => env, where
+ env is a string like "name=value". On Windows, dict keys and values are
+ Unicode strings. On Unix, they are bytes strings. */
+ PyObject *putenv_dict;
+#endif
PyObject *DirEntryType;
PyObject *ScandirIteratorType;
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -2105,7 +2115,9 @@ static int
_posix_clear(PyObject *module)
{
Py_CLEAR(_posixstate(module)->billion);
- Py_CLEAR(_posixstate(module)->posix_putenv_garbage);
+#ifdef PY_PUTENV_DICT
+ Py_CLEAR(_posixstate(module)->putenv_dict);
+#endif
Py_CLEAR(_posixstate(module)->DirEntryType);
Py_CLEAR(_posixstate(module)->ScandirIteratorType);
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -2130,7 +2142,9 @@ static int
_posix_traverse(PyObject *module, visitproc visit, void *arg)
{
Py_VISIT(_posixstate(module)->billion);
- Py_VISIT(_posixstate(module)->posix_putenv_garbage);
+#ifdef PY_PUTENV_DICT
+ Py_VISIT(_posixstate(module)->putenv_dict);
+#endif
Py_VISIT(_posixstate(module)->DirEntryType);
Py_VISIT(_posixstate(module)->ScandirIteratorType);
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -10047,23 +10061,26 @@ os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
}
#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
-#ifdef HAVE_PUTENV
+#ifdef PY_PUTENV_DICT
static void
-posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
+posix_putenv_dict_setitem(PyObject *name, PyObject *value)
{
- /* Install the first arg and newstr in posix_putenv_garbage;
+ /* Install the first arg and newstr in putenv_dict;
* this will cause previous value to be collected. This has to
* happen after the real putenv() call because the old value
* was still accessible until then. */
- if (PyDict_SetItem(_posixstate_global->posix_putenv_garbage, name, value))
+ if (PyDict_SetItem(_posixstate_global->putenv_dict, name, value))
/* really not much we can do; just leak */
PyErr_Clear();
else
Py_DECREF(value);
}
+#endif /* PY_PUTENV_DICT */
+#ifdef HAVE_PUTENV
+
#ifdef MS_WINDOWS
/*[clinic input]
os.putenv
@@ -10114,7 +10131,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
goto error;
}
- posix_putenv_garbage_setitem(name, unicode);
+ posix_putenv_dict_setitem(name, unicode);
Py_RETURN_NONE;
error:
@@ -10156,7 +10173,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
return posix_error();
}
- posix_putenv_garbage_setitem(name, bytes);
+ posix_putenv_dict_setitem(name, bytes);
Py_RETURN_NONE;
}
#endif /* MS_WINDOWS */
@@ -10189,18 +10206,20 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
return PyErr_SetFromWindowsErr(0);
}
- /* Remove the key from posix_putenv_garbage;
+#ifdef PY_PUTENV_DICT
+ /* Remove the key from putenv_dict;
* this will cause it to be collected. This has to
* happen after the real unsetenv() call because the
* old value was still accessible until then.
*/
- if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) {
+ if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
/* really not much we can do; just leak */
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
return NULL;
}
PyErr_Clear();
}
+#endif
Py_RETURN_NONE;
}
@@ -10230,18 +10249,21 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
return posix_error();
#endif
- /* Remove the key from posix_putenv_garbage;
+#ifdef PY_PUTENV_DICT
+ /* Remove the key from putenv_dict;
* this will cause it to be collected. This has to
* happen after the real unsetenv() call because the
* old value was still accessible until then.
*/
- if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) {
+ if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
/* really not much we can do; just leak */
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
return NULL;
}
PyErr_Clear();
}
+#endif
+
Py_RETURN_NONE;
}
#endif /* HAVE_UNSETENV */
@@ -14538,10 +14560,10 @@ INITFUNC(void)
Py_INCREF(PyExc_OSError);
PyModule_AddObject(m, "error", PyExc_OSError);
-#ifdef HAVE_PUTENV
+#ifdef PY_PUTENV_DICT
/* Save putenv() parameters as values here, so we can collect them when they
* get re-set with another call for the same key. */
- _posixstate(m)->posix_putenv_garbage = PyDict_New();
+ _posixstate(m)->putenv_dict = PyDict_New();
#endif
#if defined(HAVE_WAITID) && !defined(__APPLE__)