@@ -340,14 +340,50 @@ static PyObject *
340340convertenviron (void )
341341{
342342 PyObject * d ;
343+ #ifdef MS_WINDOWS
344+ wchar_t * * e ;
345+ #else
343346 char * * e ;
347+ #endif
344348 d = PyDict_New ();
345349 if (d == NULL )
346350 return NULL ;
347351#ifdef WITH_NEXT_FRAMEWORK
348352 if (environ == NULL )
349353 environ = * _NSGetEnviron ();
350354#endif
355+ #ifdef MS_WINDOWS
356+ /* _wenviron must be initialized in this way if the program is started
357+ through main() instead of wmain(). */
358+ _wgetenv (L"" );
359+ if (_wenviron == NULL )
360+ return d ;
361+ /* This part ignores errors */
362+ for (e = _wenviron ; * e != NULL ; e ++ ) {
363+ PyObject * k ;
364+ PyObject * v ;
365+ wchar_t * p = wcschr (* e , L'=' );
366+ if (p == NULL )
367+ continue ;
368+ k = PyUnicode_FromWideChar (* e , (Py_ssize_t )(p - * e ));
369+ if (k == NULL ) {
370+ PyErr_Clear ();
371+ continue ;
372+ }
373+ v = PyUnicode_FromWideChar (p + 1 , wcslen (p + 1 ));
374+ if (v == NULL ) {
375+ PyErr_Clear ();
376+ Py_DECREF (k );
377+ continue ;
378+ }
379+ if (PyDict_GetItem (d , k ) == NULL ) {
380+ if (PyDict_SetItem (d , k , v ) != 0 )
381+ PyErr_Clear ();
382+ }
383+ Py_DECREF (k );
384+ Py_DECREF (v );
385+ }
386+ #else
351387 if (environ == NULL )
352388 return d ;
353389 /* This part ignores errors */
@@ -375,6 +411,7 @@ convertenviron(void)
375411 Py_DECREF (k );
376412 Py_DECREF (v );
377413 }
414+ #endif
378415#if defined(PYOS_OS2 )
379416 {
380417 APIRET rc ;
@@ -4973,12 +5010,23 @@ static PyObject *posix_putenv_garbage;
49735010static PyObject *
49745011posix_putenv (PyObject * self , PyObject * args )
49755012{
5013+ #ifdef MS_WINDOWS
5014+ wchar_t * s1 , * s2 ;
5015+ wchar_t * newenv ;
5016+ #else
49765017 char * s1 , * s2 ;
49775018 char * newenv ;
5019+ #endif
49785020 PyObject * newstr ;
49795021 size_t len ;
49805022
4981- if (!PyArg_ParseTuple (args , "ss:putenv" , & s1 , & s2 ))
5023+ if (!PyArg_ParseTuple (args ,
5024+ #ifdef MS_WINDOWS
5025+ "uu:putenv" ,
5026+ #else
5027+ "ss:putenv" ,
5028+ #endif
5029+ & s1 , & s2 ))
49825030 return NULL ;
49835031
49845032#if defined(PYOS_OS2 )
@@ -4997,21 +5045,35 @@ posix_putenv(PyObject *self, PyObject *args)
49975045 return os2_error (rc );
49985046 } else {
49995047#endif
5000-
50015048 /* XXX This can leak memory -- not easy to fix :-( */
5002- len = strlen (s1 ) + strlen (s2 ) + 2 ;
50035049 /* len includes space for a trailing \0; the size arg to
50045050 PyString_FromStringAndSize does not count that */
5051+ #ifdef MS_WINDOWS
5052+ len = wcslen (s1 ) + wcslen (s2 ) + 2 ;
5053+ newstr = PyUnicode_FromUnicode (NULL , (int )len - 1 );
5054+ #else
5055+ len = strlen (s1 ) + strlen (s2 ) + 2 ;
50055056 newstr = PyString_FromStringAndSize (NULL , (int )len - 1 );
5057+ #endif
50065058 if (newstr == NULL )
50075059 return PyErr_NoMemory ();
5060+ #ifdef MS_WINDOWS
5061+ newenv = PyUnicode_AsUnicode (newstr );
5062+ _snwprintf (newenv , len , L"%s=%s" , s1 , s2 );
5063+ if (_wputenv (newenv )) {
5064+ Py_DECREF (newstr );
5065+ posix_error ();
5066+ return NULL ;
5067+ }
5068+ #else
50085069 newenv = PyString_AS_STRING (newstr );
50095070 PyOS_snprintf (newenv , len , "%s=%s" , s1 , s2 );
50105071 if (putenv (newenv )) {
50115072 Py_DECREF (newstr );
50125073 posix_error ();
50135074 return NULL ;
50145075 }
5076+ #endif
50155077 /* Install the first arg and newstr in posix_putenv_garbage;
50165078 * this will cause previous value to be collected. This has to
50175079 * happen after the real putenv() call because the old value
0 commit comments