Skip to content

Commit 623ed61

Browse files
authored
bpo-39406: Add PY_PUTENV_DICT macro to posixmodule.c (GH-18106)
Rename posix_putenv_garbage to putenv_dict.
1 parent 56cd371 commit 623ed61

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

Modules/posixmodule.c

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -819,9 +819,19 @@ dir_fd_converter(PyObject *o, void *p)
819819
}
820820
}
821821

822+
#ifdef HAVE_PUTENV
823+
# define PY_PUTENV_DICT
824+
#endif
825+
822826
typedef struct {
823827
PyObject *billion;
824-
PyObject *posix_putenv_garbage;
828+
#ifdef PY_PUTENV_DICT
829+
/* putenv() and _wputenv() requires that the caller manages the environment
830+
variable memory. Use a Python dictionary for that: name => env, where
831+
env is a string like "name=value". On Windows, dict keys and values are
832+
Unicode strings. On Unix, they are bytes strings. */
833+
PyObject *putenv_dict;
834+
#endif
825835
PyObject *DirEntryType;
826836
PyObject *ScandirIteratorType;
827837
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -2105,7 +2115,9 @@ static int
21052115
_posix_clear(PyObject *module)
21062116
{
21072117
Py_CLEAR(_posixstate(module)->billion);
2108-
Py_CLEAR(_posixstate(module)->posix_putenv_garbage);
2118+
#ifdef PY_PUTENV_DICT
2119+
Py_CLEAR(_posixstate(module)->putenv_dict);
2120+
#endif
21092121
Py_CLEAR(_posixstate(module)->DirEntryType);
21102122
Py_CLEAR(_posixstate(module)->ScandirIteratorType);
21112123
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -2130,7 +2142,9 @@ static int
21302142
_posix_traverse(PyObject *module, visitproc visit, void *arg)
21312143
{
21322144
Py_VISIT(_posixstate(module)->billion);
2133-
Py_VISIT(_posixstate(module)->posix_putenv_garbage);
2145+
#ifdef PY_PUTENV_DICT
2146+
Py_VISIT(_posixstate(module)->putenv_dict);
2147+
#endif
21342148
Py_VISIT(_posixstate(module)->DirEntryType);
21352149
Py_VISIT(_posixstate(module)->ScandirIteratorType);
21362150
#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,
1004710061
}
1004810062
#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
1004910063

10050-
#ifdef HAVE_PUTENV
1005110064

10065+
#ifdef PY_PUTENV_DICT
1005210066
static void
10053-
posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
10067+
posix_putenv_dict_setitem(PyObject *name, PyObject *value)
1005410068
{
10055-
/* Install the first arg and newstr in posix_putenv_garbage;
10069+
/* Install the first arg and newstr in putenv_dict;
1005610070
* this will cause previous value to be collected. This has to
1005710071
* happen after the real putenv() call because the old value
1005810072
* was still accessible until then. */
10059-
if (PyDict_SetItem(_posixstate_global->posix_putenv_garbage, name, value))
10073+
if (PyDict_SetItem(_posixstate_global->putenv_dict, name, value))
1006010074
/* really not much we can do; just leak */
1006110075
PyErr_Clear();
1006210076
else
1006310077
Py_DECREF(value);
1006410078
}
10079+
#endif /* PY_PUTENV_DICT */
1006510080

1006610081

10082+
#ifdef HAVE_PUTENV
10083+
1006710084
#ifdef MS_WINDOWS
1006810085
/*[clinic input]
1006910086
os.putenv
@@ -10114,7 +10131,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
1011410131
goto error;
1011510132
}
1011610133

10117-
posix_putenv_garbage_setitem(name, unicode);
10134+
posix_putenv_dict_setitem(name, unicode);
1011810135
Py_RETURN_NONE;
1011910136

1012010137
error:
@@ -10156,7 +10173,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
1015610173
return posix_error();
1015710174
}
1015810175

10159-
posix_putenv_garbage_setitem(name, bytes);
10176+
posix_putenv_dict_setitem(name, bytes);
1016010177
Py_RETURN_NONE;
1016110178
}
1016210179
#endif /* MS_WINDOWS */
@@ -10189,18 +10206,20 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
1018910206
return PyErr_SetFromWindowsErr(0);
1019010207
}
1019110208

10192-
/* Remove the key from posix_putenv_garbage;
10209+
#ifdef PY_PUTENV_DICT
10210+
/* Remove the key from putenv_dict;
1019310211
* this will cause it to be collected. This has to
1019410212
* happen after the real unsetenv() call because the
1019510213
* old value was still accessible until then.
1019610214
*/
10197-
if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) {
10215+
if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
1019810216
/* really not much we can do; just leak */
1019910217
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
1020010218
return NULL;
1020110219
}
1020210220
PyErr_Clear();
1020310221
}
10222+
#endif
1020410223

1020510224
Py_RETURN_NONE;
1020610225
}
@@ -10230,18 +10249,21 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
1023010249
return posix_error();
1023110250
#endif
1023210251

10233-
/* Remove the key from posix_putenv_garbage;
10252+
#ifdef PY_PUTENV_DICT
10253+
/* Remove the key from putenv_dict;
1023410254
* this will cause it to be collected. This has to
1023510255
* happen after the real unsetenv() call because the
1023610256
* old value was still accessible until then.
1023710257
*/
10238-
if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) {
10258+
if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
1023910259
/* really not much we can do; just leak */
1024010260
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
1024110261
return NULL;
1024210262
}
1024310263
PyErr_Clear();
1024410264
}
10265+
#endif
10266+
1024510267
Py_RETURN_NONE;
1024610268
}
1024710269
#endif /* HAVE_UNSETENV */
@@ -14538,10 +14560,10 @@ INITFUNC(void)
1453814560
Py_INCREF(PyExc_OSError);
1453914561
PyModule_AddObject(m, "error", PyExc_OSError);
1454014562

14541-
#ifdef HAVE_PUTENV
14563+
#ifdef PY_PUTENV_DICT
1454214564
/* Save putenv() parameters as values here, so we can collect them when they
1454314565
* get re-set with another call for the same key. */
14544-
_posixstate(m)->posix_putenv_garbage = PyDict_New();
14566+
_posixstate(m)->putenv_dict = PyDict_New();
1454514567
#endif
1454614568

1454714569
#if defined(HAVE_WAITID) && !defined(__APPLE__)

0 commit comments

Comments
 (0)