diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2010-05-06 22:05:07 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2010-05-06 22:05:07 (GMT) |
commit | 84ae1180063a6f9fc39c22a5977b49aaac8c3b3c (patch) | |
tree | 188bac431d36a612b99a98fc263a0baa96ce67c2 /Modules | |
parent | d930b63583a8dc1ece9407652636209a3d396149 (diff) | |
download | cpython-84ae1180063a6f9fc39c22a5977b49aaac8c3b3c.zip cpython-84ae1180063a6f9fc39c22a5977b49aaac8c3b3c.tar.gz cpython-84ae1180063a6f9fc39c22a5977b49aaac8c3b3c.tar.bz2 |
Issue #8603: Create a bytes version of os.environ for Unix
Create os.environb mapping and os.getenvb() function, os.unsetenv() encodes str
argument to the file system encoding with the surrogateescape error handler
(instead of utf8/strict) and accepts bytes, and posix.environ keys and values
are bytes.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/posixmodule.c | 79 |
1 files changed, 55 insertions, 24 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index ac866d7..0d6f8f0 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -498,14 +498,12 @@ convertenviron(void) char *p = strchr(*e, '='); if (p == NULL) continue; - k = PyUnicode_Decode(*e, (int)(p-*e), - Py_FileSystemDefaultEncoding, "surrogateescape"); + k = PyBytes_FromStringAndSize(*e, (int)(p-*e)); if (k == NULL) { PyErr_Clear(); continue; } - v = PyUnicode_Decode(p+1, strlen(p+1), - Py_FileSystemDefaultEncoding, "surrogateescape"); + v = PyBytes_FromStringAndSize(p+1, strlen(p+1)); if (v == NULL) { PyErr_Clear(); Py_DECREF(k); @@ -5301,7 +5299,7 @@ posix_putenv(PyObject *self, PyObject *args) char *s1, *s2; char *newenv; #endif - PyObject *newstr; + PyObject *newstr = NULL; size_t len; #ifdef MS_WINDOWS @@ -5324,15 +5322,19 @@ posix_putenv(PyObject *self, PyObject *args) APIRET rc; rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH); - if (rc != NO_ERROR) - return os2_error(rc); + if (rc != NO_ERROR) { + os2_error(rc); + goto error; + } } else if (stricmp(s1, "ENDLIBPATH") == 0) { APIRET rc; rc = DosSetExtLIBPATH(s2, END_LIBPATH); - if (rc != NO_ERROR) - return os2_error(rc); + if (rc != NO_ERROR) { + os2_error(rc); + goto error; + } } else { #endif /* XXX This can leak memory -- not easy to fix :-( */ @@ -5342,36 +5344,40 @@ posix_putenv(PyObject *self, PyObject *args) len = wcslen(s1) + wcslen(s2) + 2; newstr = PyUnicode_FromUnicode(NULL, (int)len - 1); #else - len = strlen(s1) + strlen(s2) + 2; + len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2; newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1); #endif - if (newstr == NULL) - return PyErr_NoMemory(); + if (newstr == NULL) { + PyErr_NoMemory(); + goto error; + } #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; + goto error; } #else newenv = PyBytes_AS_STRING(newstr); PyOS_snprintf(newenv, len, "%s=%s", s1, s2); if (putenv(newenv)) { - Py_DECREF(newstr); - Py_DECREF(os1); - Py_DECREF(os2); posix_error(); - return NULL; + goto error; } #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 * was still accessible until then. */ if (PyDict_SetItem(posix_putenv_garbage, - PyTuple_GET_ITEM(args, 0), newstr)) { +#ifdef MS_WINDOWS + PyTuple_GET_ITEM(args, 0), +#else + os1, +#endif + newstr)) { /* really not much we can do; just leak */ PyErr_Clear(); } @@ -5382,12 +5388,20 @@ posix_putenv(PyObject *self, PyObject *args) #if defined(PYOS_OS2) } #endif + #ifndef MS_WINDOWS Py_DECREF(os1); Py_DECREF(os2); #endif - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; + +error: +#ifndef MS_WINDOWS + Py_DECREF(os1); + Py_DECREF(os2); +#endif + Py_XDECREF(newstr); + return NULL; } #endif /* putenv */ @@ -5399,10 +5413,20 @@ Delete an environment variable."); static PyObject * posix_unsetenv(PyObject *self, PyObject *args) { +#ifdef MS_WINDOWS char *s1; if (!PyArg_ParseTuple(args, "s:unsetenv", &s1)) return NULL; +#else + PyObject *os1; + char *s1; + + if (!PyArg_ParseTuple(args, "O&:unsetenv", + PyUnicode_FSConverter, &os1)) + return NULL; + s1 = PyBytes_AsString(os1); +#endif unsetenv(s1); @@ -5412,13 +5436,20 @@ posix_unsetenv(PyObject *self, PyObject *args) * old value was still accessible until then. */ if (PyDict_DelItem(posix_putenv_garbage, - PyTuple_GET_ITEM(args, 0))) { +#ifdef MS_WINDOWS + PyTuple_GET_ITEM(args, 0) +#else + os1 +#endif + )) { /* really not much we can do; just leak */ PyErr_Clear(); } - Py_INCREF(Py_None); - return Py_None; +#ifndef MS_WINDOWS + Py_DECREF(os1); +#endif + Py_RETURN_NONE; } #endif /* unsetenv */ |