diff options
author | Victor Stinner <vstinner@python.org> | 2020-01-21 19:25:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-21 19:25:32 +0100 |
commit | 623ed6171eae35af7fd2e804dfd9c832c05c5d48 (patch) | |
tree | f48cb78948e40705749cb10c734c7da844bdfb60 /Modules/posixmodule.c | |
parent | 56cd3710a1ea3ba872d345ea1bebc86ed08bc8b8 (diff) | |
download | cpython-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/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 52 |
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__) |