Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f78f12a

Browse files
author
Thomas Heller
committed
Issue 1406: use widechar api for os.environ, on Windows.
1 parent 8e42a0a commit f78f12a

1 file changed

Lines changed: 65 additions & 3 deletions

File tree

Modules/posixmodule.c

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,14 +340,50 @@ static PyObject *
340340
convertenviron(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;
49735010
static PyObject *
49745011
posix_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

Comments
 (0)