@@ -10083,23 +10083,9 @@ posix_putenv_dict_setitem(PyObject *name, PyObject *value)
1008310083
1008410084
1008510085#ifdef MS_WINDOWS
10086- /*[clinic input]
10087- os.putenv
10088-
10089- name: unicode
10090- value: unicode
10091- /
10092-
10093- Change or add an environment variable.
10094- [clinic start generated code]*/
10095-
10096- static PyObject *
10097- os_putenv_impl (PyObject * module , PyObject * name , PyObject * value )
10098- /*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
10086+ static PyObject *
10087+ win32_putenv (PyObject * name , PyObject * value )
1009910088{
10100- const wchar_t * env ;
10101- Py_ssize_t size ;
10102-
1010310089 /* Search from index 1 because on Windows starting '=' is allowed for
1010410090 defining hidden environment variables. */
1010510091 if (PyUnicode_GET_LENGTH (name ) == 0 ||
@@ -10108,36 +10094,68 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
1010810094 PyErr_SetString (PyExc_ValueError , "illegal environment variable name" );
1010910095 return NULL ;
1011010096 }
10111- PyObject * unicode = PyUnicode_FromFormat ("%U=%U" , name , value );
10097+ PyObject * unicode ;
10098+ if (value != NULL ) {
10099+ unicode = PyUnicode_FromFormat ("%U=%U" , name , value );
10100+ }
10101+ else {
10102+ unicode = PyUnicode_FromFormat ("%U=" , name );
10103+ }
1011210104 if (unicode == NULL ) {
1011310105 return NULL ;
1011410106 }
1011510107
10116- env = PyUnicode_AsUnicodeAndSize (unicode , & size );
10117- if (env == NULL )
10118- goto error ;
10108+ Py_ssize_t size ;
10109+ /* PyUnicode_AsWideCharString() rejects embedded null characters */
10110+ wchar_t * env = PyUnicode_AsWideCharString (unicode , & size );
10111+ Py_DECREF (unicode );
10112+
10113+ if (env == NULL ) {
10114+ return NULL ;
10115+ }
1011910116 if (size > _MAX_ENV ) {
1012010117 PyErr_Format (PyExc_ValueError ,
1012110118 "the environment variable is longer than %u characters" ,
1012210119 _MAX_ENV );
10123- goto error ;
10124- }
10125- if (wcslen (env ) != (size_t )size ) {
10126- PyErr_SetString (PyExc_ValueError , "embedded null character" );
10127- goto error ;
10120+ PyMem_Free (env );
10121+ return NULL ;
1012810122 }
1012910123
10130- if (_wputenv (env )) {
10124+ /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10125+ Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10126+ and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10127+
10128+ Prefer _wputenv() to be compatible with C libraries using CRT
10129+ variables and CRT functions using these variables (ex: getenv()). */
10130+ int err = _wputenv (env );
10131+ PyMem_Free (env );
10132+
10133+ if (err ) {
1013110134 posix_error ();
10132- goto error ;
10135+ return NULL ;
1013310136 }
10134- Py_DECREF (unicode );
1013510137
1013610138 Py_RETURN_NONE ;
10139+ }
10140+ #endif
1013710141
10138- error :
10139- Py_DECREF (unicode );
10140- return NULL ;
10142+
10143+ #ifdef MS_WINDOWS
10144+ /*[clinic input]
10145+ os.putenv
10146+
10147+ name: unicode
10148+ value: unicode
10149+ /
10150+
10151+ Change or add an environment variable.
10152+ [clinic start generated code]*/
10153+
10154+ static PyObject *
10155+ os_putenv_impl (PyObject * module , PyObject * name , PyObject * value )
10156+ /*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
10157+ {
10158+ return win32_putenv (name , value );
1014110159}
1014210160/* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */
1014310161#elif (defined(HAVE_SETENV ) || defined(HAVE_PUTENV )) && !defined(MS_WINDOWS )
@@ -10186,7 +10204,23 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
1018610204#endif /* defined(HAVE_SETENV) || defined(HAVE_PUTENV) */
1018710205
1018810206
10189- #ifdef HAVE_UNSETENV
10207+ #ifdef MS_WINDOWS
10208+ /*[clinic input]
10209+ os.unsetenv
10210+ name: unicode
10211+ /
10212+
10213+ Delete an environment variable.
10214+ [clinic start generated code]*/
10215+
10216+ static PyObject *
10217+ os_unsetenv_impl (PyObject * module , PyObject * name )
10218+ /*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10219+ {
10220+ return win32_putenv (name , NULL );
10221+ }
10222+ /* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */
10223+ #elif defined(HAVE_UNSETENV ) && !defined(MS_WINDOWS )
1019010224/*[clinic input]
1019110225os.unsetenv
1019210226 name: FSConverter
@@ -10199,16 +10233,13 @@ static PyObject *
1019910233os_unsetenv_impl (PyObject * module , PyObject * name )
1020010234/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
1020110235{
10202- #ifndef HAVE_BROKEN_UNSETENV
10203- int err ;
10204- #endif
10205-
1020610236#ifdef HAVE_BROKEN_UNSETENV
1020710237 unsetenv (PyBytes_AS_STRING (name ));
1020810238#else
10209- err = unsetenv (PyBytes_AS_STRING (name ));
10210- if (err )
10239+ int err = unsetenv (PyBytes_AS_STRING (name ));
10240+ if (err ) {
1021110241 return posix_error ();
10242+ }
1021210243#endif
1021310244
1021410245#ifdef PY_PUTENV_DICT
0 commit comments