summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2007-10-30 18:34:07 (GMT)
committerGuido van Rossum <guido@python.org>2007-10-30 18:34:07 (GMT)
commit826d8973ac52a0a8155ef857c8a9bf18a90b11ac (patch)
tree228f7830ba30118bed52db846a39b2ef1f9c0fda
parent1cd5bd2a2e600d0f29f9dcfbb9ea922cb1cd006f (diff)
downloadcpython-826d8973ac52a0a8155ef857c8a9bf18a90b11ac.zip
cpython-826d8973ac52a0a8155ef857c8a9bf18a90b11ac.tar.gz
cpython-826d8973ac52a0a8155ef857c8a9bf18a90b11ac.tar.bz2
Patch 1352 (continued in issue 1329) by Christian Heimes.
Before sys.stderr is set to the proper thing, set it to a really simple file-like object that can print tracebacks using direct file descriptor I/O. This is handy for debugging.
-rw-r--r--Include/fileobject.h7
-rw-r--r--Objects/fileobject.c118
-rw-r--r--Objects/object.c3
-rw-r--r--Python/pythonrun.c9
4 files changed, 136 insertions, 1 deletions
diff --git a/Include/fileobject.h b/Include/fileobject.h
index ae127da..40d871a 100644
--- a/Include/fileobject.h
+++ b/Include/fileobject.h
@@ -21,6 +21,13 @@ PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
*/
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
+/* Internal API
+
+ The std printer acts as a preliminary sys.stderr until the new io
+ infrastructure is in place. */
+PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int);
+PyAPI_DATA(PyTypeObject) PyStdPrinter_Type;
+
#ifdef __cplusplus
}
#endif
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 4e18480..dc0f1fd 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -325,6 +325,124 @@ Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
return buf;
}
+/* **************************** std printer **************************** */
+
+typedef struct {
+ PyObject_HEAD
+ int fd;
+} PyStdPrinter_Object;
+
+static PyObject *
+stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
+{
+ PyStdPrinter_Object *self;
+
+ assert(type != NULL && type->tp_alloc != NULL);
+
+ self = (PyStdPrinter_Object *) type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->fd = -1;
+ }
+
+ return (PyObject *) self;
+}
+
+PyObject *
+PyFile_NewStdPrinter(int fd)
+{
+ PyStdPrinter_Object *self;
+
+ if (fd != 1 && fd != 2) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ self = PyObject_New(PyStdPrinter_Object,
+ &PyStdPrinter_Type);
+ self->fd = fd;
+ return (PyObject*)self;
+}
+
+PyObject *
+stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
+{
+ char *c;
+ Py_ssize_t n;
+
+ if (self->fd < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTuple(args, "s#", &c, &n)) {
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ errno = 0;
+ n = write(self->fd, c, n);
+ Py_END_ALLOW_THREADS
+
+ if (n < 0) {
+ if (errno == EAGAIN)
+ Py_RETURN_NONE;
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+
+ return PyInt_FromSsize_t(n);
+}
+
+static PyMethodDef stdprinter_methods[] = {
+ {"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyStdPrinter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "stderrprinter", /* tp_name */
+ sizeof(PyStdPrinter_Object), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ stdprinter_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ stdprinter_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+
#ifdef __cplusplus
}
#endif
diff --git a/Objects/object.c b/Objects/object.c
index f6d125f..77ddb1d 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1595,6 +1595,9 @@ _Py_ReadyTypes(void)
if (PyType_Ready(&PyCode_Type) < 0)
Py_FatalError("Can't initialize 'code'");
+
+ if (PyType_Ready(&PyStdPrinter_Type) < 0)
+ Py_FatalError("Can't initialize StdPrinter");
}
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 76da8fb..ec9ed02 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -151,7 +151,7 @@ Py_InitializeEx(int install_sigs)
{
PyInterpreterState *interp;
PyThreadState *tstate;
- PyObject *bimod, *sysmod;
+ PyObject *bimod, *sysmod, *pstderr;
char *p;
#if defined(HAVE_LANGINFO_H) && defined(CODESET)
char *codeset;
@@ -228,6 +228,13 @@ Py_InitializeEx(int install_sigs)
PyDict_SetItemString(interp->sysdict, "modules",
interp->modules);
+ /* Set up a preliminary stderr printer until we have enough
+ infrastructure for the io module in place. */
+ pstderr = PyFile_NewStdPrinter(fileno(stderr));
+ if (pstderr == NULL)
+ Py_FatalError("Py_Initialize: can't set preliminary stderr");
+ PySys_SetObject("stderr", pstderr);
+
_PyImport_Init();
/* initialize builtin exceptions */