Issue #25182: The stdprinter (used as sys.stderr before the io module is

imported at startup) now uses the backslashreplace error handler.
This commit is contained in:
Serhiy Storchaka 2015-09-30 15:46:53 +03:00
parent b5102e3550
commit a59018c7ab
2 changed files with 25 additions and 6 deletions

View file

@ -372,8 +372,11 @@ PyFile_NewStdPrinter(int fd)
static PyObject *
stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
{
char *c;
PyObject *unicode;
PyObject *bytes = NULL;
char *str;
Py_ssize_t n;
int _errno;
if (self->fd < 0) {
/* fd might be invalid on Windows
@ -383,24 +386,37 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
Py_RETURN_NONE;
}
if (!PyArg_ParseTuple(args, "s", &c)) {
if (!PyArg_ParseTuple(args, "U", &unicode))
return NULL;
/* encode Unicode to UTF-8 */
str = PyUnicode_AsUTF8AndSize(unicode, &n);
if (str == NULL) {
PyErr_Clear();
bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace");
if (bytes == NULL)
return NULL;
if (PyBytes_AsStringAndSize(bytes, &str, &n) < 0) {
Py_DECREF(bytes);
return NULL;
}
}
n = strlen(c);
Py_BEGIN_ALLOW_THREADS
errno = 0;
#ifdef MS_WINDOWS
if (n > INT_MAX)
n = INT_MAX;
n = write(self->fd, c, (int)n);
n = write(self->fd, str, (int)n);
#else
n = write(self->fd, c, n);
n = write(self->fd, str, n);
#endif
_errno = errno;
Py_END_ALLOW_THREADS
Py_XDECREF(bytes);
if (n < 0) {
if (errno == EAGAIN)
if (_errno == EAGAIN)
Py_RETURN_NONE;
PyErr_SetFromErrno(PyExc_IOError);
return NULL;