comparison Python/sysmodule.c @ 60889:86fadaebcf66

Issue #8124: PySys_WriteStdout() and PySys_WriteStderr() don't execute indirectly Python signal handlers anymore because mywrite() ignores exceptions (KeyboardInterrupt).
author Victor Stinner <victor.stinner@haypocalc.com>
date Fri, 23 Apr 2010 12:02:30 +0000
parents 29fac4b1a51e
children cab14be0ada1
comparison
equal deleted inserted replaced
60887:e6564da01718 60889:86fadaebcf66
1761 Py_DECREF(a); 1761 Py_DECREF(a);
1762 } 1762 }
1763 Py_DECREF(av); 1763 Py_DECREF(av);
1764 } 1764 }
1765 1765
1766 /* Reimplementation of PyFile_WriteString() no calling indirectly
1767 PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
1768
1769 static int
1770 sys_pyfile_write(const char *text, PyObject *file)
1771 {
1772 PyObject *unicode = NULL, *writer = NULL, *args = NULL, *result = NULL;
1773 int err;
1774
1775 unicode = PyUnicode_FromString(text);
1776 if (unicode == NULL)
1777 goto error;
1778
1779 writer = PyObject_GetAttrString(file, "write");
1780 if (writer == NULL)
1781 goto error;
1782
1783 args = PyTuple_Pack(1, unicode);
1784 if (args == NULL)
1785 goto error;
1786
1787 result = PyEval_CallObject(writer, args);
1788 if (result == NULL) {
1789 goto error;
1790 } else {
1791 err = 0;
1792 goto finally;
1793 }
1794
1795 error:
1796 err = -1;
1797 finally:
1798 Py_XDECREF(unicode);
1799 Py_XDECREF(writer);
1800 Py_XDECREF(args);
1801 Py_XDECREF(result);
1802 return err;
1803 }
1804
1766 1805
1767 /* APIs to write to sys.stdout or sys.stderr using a printf-like interface. 1806 /* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
1768 Adapted from code submitted by Just van Rossum. 1807 Adapted from code submitted by Just van Rossum.
1769 1808
1770 PySys_WriteStdout(format, ...) 1809 PySys_WriteStdout(format, ...)
1771 PySys_WriteStderr(format, ...) 1810 PySys_WriteStderr(format, ...)
1772 1811
1773 The first function writes to sys.stdout; the second to sys.stderr. When 1812 The first function writes to sys.stdout; the second to sys.stderr. When
1774 there is a problem, they write to the real (C level) stdout or stderr; 1813 there is a problem, they write to the real (C level) stdout or stderr;
1775 no exceptions are raised. 1814 no exceptions are raised.
1815
1816 PyErr_CheckSignals() is not called to avoid the execution of the Python
1817 signal handlers: they may raise a new exception whereas mywrite() ignores
1818 all exceptions.
1776 1819
1777 Both take a printf-style format string as their first argument followed 1820 Both take a printf-style format string as their first argument followed
1778 by a variable length argument list determined by the format string. 1821 by a variable length argument list determined by the format string.
1779 1822
1780 *** WARNING *** 1823 *** WARNING ***
1797 int written; 1840 int written;
1798 1841
1799 PyErr_Fetch(&error_type, &error_value, &error_traceback); 1842 PyErr_Fetch(&error_type, &error_value, &error_traceback);
1800 file = PySys_GetObject(name); 1843 file = PySys_GetObject(name);
1801 written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); 1844 written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
1802 if (PyFile_WriteString(buffer, file) != 0) { 1845 if (sys_pyfile_write(buffer, file) != 0) {
1803 PyErr_Clear(); 1846 PyErr_Clear();
1804 fputs(buffer, fp); 1847 fputs(buffer, fp);
1805 } 1848 }
1806 if (written < 0 || (size_t)written >= sizeof(buffer)) { 1849 if (written < 0 || (size_t)written >= sizeof(buffer)) {
1807 const char *truncated = "... truncated"; 1850 const char *truncated = "... truncated";
1808 if (PyFile_WriteString(truncated, file) != 0) { 1851 if (sys_pyfile_write(truncated, file) != 0) {
1809 PyErr_Clear(); 1852 PyErr_Clear();
1810 fputs(truncated, fp); 1853 fputs(truncated, fp);
1811 } 1854 }
1812 } 1855 }
1813 PyErr_Restore(error_type, error_value, error_traceback); 1856 PyErr_Restore(error_type, error_value, error_traceback);