@@ -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+
822826typedef 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
1005210066static 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]
1006910086os.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
1012010137error :
@@ -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