[Python-3000-checkins] r58916 - python/branches/py3k/Modules/posixmodule.c

thomas.heller python-3000-checkins at python.org
Thu Nov 8 20:33:06 CET 2007


Author: thomas.heller
Date: Thu Nov  8 20:33:05 2007
New Revision: 58916

Modified:
   python/branches/py3k/Modules/posixmodule.c
Log:
Issue 1406: use widechar api for os.environ, on Windows.

Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c	(original)
+++ python/branches/py3k/Modules/posixmodule.c	Thu Nov  8 20:33:05 2007
@@ -340,7 +340,11 @@
 convertenviron(void)
 {
 	PyObject *d;
+#ifdef MS_WINDOWS
+	wchar_t **e;
+#else
 	char **e;
+#endif
 	d = PyDict_New();
 	if (d == NULL)
 		return NULL;
@@ -348,6 +352,38 @@
 	if (environ == NULL)
 		environ = *_NSGetEnviron();
 #endif
+#ifdef MS_WINDOWS
+	/* _wenviron must be initialized in this way if the program is started
+	   through main() instead of wmain(). */
+	_wgetenv(L"");
+	if (_wenviron == NULL)
+		return d;
+	/* This part ignores errors */
+	for (e = _wenviron; *e != NULL; e++) {
+		PyObject *k;
+		PyObject *v;
+		wchar_t *p = wcschr(*e, L'=');
+		if (p == NULL)
+			continue;
+		k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
+		if (k == NULL) {
+			PyErr_Clear();
+			continue;
+		}
+		v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
+		if (v == NULL) {
+			PyErr_Clear();
+			Py_DECREF(k);
+			continue;
+		}
+		if (PyDict_GetItem(d, k) == NULL) {
+			if (PyDict_SetItem(d, k, v) != 0)
+				PyErr_Clear();
+		}
+		Py_DECREF(k);
+		Py_DECREF(v);
+	}
+#else
 	if (environ == NULL)
 		return d;
 	/* This part ignores errors */
@@ -375,6 +411,7 @@
 		Py_DECREF(k);
 		Py_DECREF(v);
 	}
+#endif
 #if defined(PYOS_OS2)
     {
         APIRET rc;
@@ -4973,12 +5010,23 @@
 static PyObject *
 posix_putenv(PyObject *self, PyObject *args)
 {
+#ifdef MS_WINDOWS
+        wchar_t *s1, *s2;
+        wchar_t *newenv;
+#else
         char *s1, *s2;
         char *newenv;
+#endif
 	PyObject *newstr;
 	size_t len;
 
-	if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
+	if (!PyArg_ParseTuple(args,
+#ifdef MS_WINDOWS
+			      "uu:putenv",
+#else
+			      "ss:putenv",
+#endif
+			      &s1, &s2))
 		return NULL;
 
 #if defined(PYOS_OS2)
@@ -4997,14 +5045,27 @@
             return os2_error(rc);
     } else {
 #endif
-
 	/* XXX This can leak memory -- not easy to fix :-( */
-	len = strlen(s1) + strlen(s2) + 2;
 	/* len includes space for a trailing \0; the size arg to
 	   PyString_FromStringAndSize does not count that */
+#ifdef MS_WINDOWS
+	len = wcslen(s1) + wcslen(s2) + 2;
+	newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
+#else
+	len = strlen(s1) + strlen(s2) + 2;
 	newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
+#endif
 	if (newstr == NULL)
 		return PyErr_NoMemory();
+#ifdef MS_WINDOWS
+	newenv = PyUnicode_AsUnicode(newstr);
+	_snwprintf(newenv, len, L"%s=%s", s1, s2);
+	if (_wputenv(newenv)) {
+                Py_DECREF(newstr);
+                posix_error();
+                return NULL;
+	}
+#else
 	newenv = PyString_AS_STRING(newstr);
 	PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
 	if (putenv(newenv)) {
@@ -5012,6 +5073,7 @@
                 posix_error();
                 return NULL;
 	}
+#endif
 	/* Install the first arg and newstr in posix_putenv_garbage;
 	 * this will cause previous value to be collected.  This has to
 	 * happen after the real putenv() call because the old value


More information about the Python-3000-checkins mailing list