summaryrefslogtreecommitdiffstats
path: root/Modules/faulthandler.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-03-12 14:32:03 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-03-12 14:32:03 (GMT)
commit95bb714ff759312479cf87b1ff6ec0c14c41b328 (patch)
tree80d61b4f87737f3242a622fd37702be059af6f5b /Modules/faulthandler.c
parentebaa81f3b1293a5936c72a0261af2a3ea46a3f27 (diff)
downloadcpython-95bb714ff759312479cf87b1ff6ec0c14c41b328.zip
cpython-95bb714ff759312479cf87b1ff6ec0c14c41b328.tar.gz
cpython-95bb714ff759312479cf87b1ff6ec0c14c41b328.tar.bz2
Issue #23566: enable(), register(), dump_traceback() and dump_traceback_later()
functions of faulthandler now accept file descriptors. Patch by Wei Wu.
Diffstat (limited to 'Modules/faulthandler.c')
-rw-r--r--Modules/faulthandler.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index 4643c0e..def7b29 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -133,32 +133,46 @@ static stack_t stack;
call its flush() method.
If file is NULL or Py_None, use sys.stderr as the new file.
+ If file is an integer, it will be treated as file descriptor.
- On success, return the new file and write the file descriptor into *p_fd.
- On error, return NULL. */
+ On success, return the file descriptor and write the new file into *file_ptr.
+ On error, return -1. */
-static PyObject*
-faulthandler_get_fileno(PyObject *file, int *p_fd)
+static int
+faulthandler_get_fileno(PyObject **file_ptr)
{
PyObject *result;
long fd_long;
int fd;
+ PyObject *file = *file_ptr;
if (file == NULL || file == Py_None) {
file = _PySys_GetObjectId(&PyId_stderr);
if (file == NULL) {
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
- return NULL;
+ return -1;
}
if (file == Py_None) {
PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
- return NULL;
+ return -1;
+ }
+ }
+ else if (PyLong_Check(file)) {
+ fd = _PyLong_AsInt(file);
+ if (fd == -1 && PyErr_Occurred())
+ return -1;
+ if (fd < 0 || !_PyVerify_fd(fd)) {
+ PyErr_SetString(PyExc_ValueError,
+ "file is not a valid file descripter");
+ return -1;
}
+ *file_ptr = NULL;
+ return fd;
}
result = _PyObject_CallMethodId(file, &PyId_fileno, "");
if (result == NULL)
- return NULL;
+ return -1;
fd = -1;
if (PyLong_Check(result)) {
@@ -171,7 +185,7 @@ faulthandler_get_fileno(PyObject *file, int *p_fd)
if (fd == -1) {
PyErr_SetString(PyExc_RuntimeError,
"file.fileno() is not a valid file descriptor");
- return NULL;
+ return -1;
}
result = _PyObject_CallMethodId(file, &PyId_flush, "");
@@ -181,8 +195,8 @@ faulthandler_get_fileno(PyObject *file, int *p_fd)
/* ignore flush() error */
PyErr_Clear();
}
- *p_fd = fd;
- return file;
+ *file_ptr = file;
+ return fd;
}
/* Get the state of the current thread: only call this function if the current
@@ -215,8 +229,8 @@ faulthandler_dump_traceback_py(PyObject *self,
&file, &all_threads))
return NULL;
- file = faulthandler_get_fileno(file, &fd);
- if (file == NULL)
+ fd = faulthandler_get_fileno(&file);
+ if (fd < 0)
return NULL;
tstate = get_thread_state();
@@ -339,8 +353,8 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
"|Oi:enable", kwlist, &file, &all_threads))
return NULL;
- file = faulthandler_get_fileno(file, &fd);
- if (file == NULL)
+ fd = faulthandler_get_fileno(&file);
+ if (fd < 0)
return NULL;
tstate = get_thread_state();
@@ -348,7 +362,7 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
return NULL;
Py_XDECREF(fatal_error.file);
- Py_INCREF(file);
+ Py_XINCREF(file);
fatal_error.file = file;
fatal_error.fd = fd;
fatal_error.all_threads = all_threads;
@@ -553,8 +567,8 @@ faulthandler_dump_traceback_later(PyObject *self,
if (tstate == NULL)
return NULL;
- file = faulthandler_get_fileno(file, &fd);
- if (file == NULL)
+ fd = faulthandler_get_fileno(&file);
+ if (fd < 0)
return NULL;
/* format the timeout */
@@ -567,7 +581,7 @@ faulthandler_dump_traceback_later(PyObject *self,
cancel_dump_traceback_later();
Py_XDECREF(thread.file);
- Py_INCREF(file);
+ Py_XINCREF(file);
thread.file = file;
thread.fd = fd;
thread.timeout_us = timeout_us;
@@ -737,8 +751,8 @@ faulthandler_register_py(PyObject *self,
if (tstate == NULL)
return NULL;
- file = faulthandler_get_fileno(file, &fd);
- if (file == NULL)
+ fd = faulthandler_get_fileno(&file);
+ if (fd < 0)
return NULL;
if (user_signals == NULL) {
@@ -760,7 +774,7 @@ faulthandler_register_py(PyObject *self,
}
Py_XDECREF(user->file);
- Py_INCREF(file);
+ Py_XINCREF(file);
user->file = file;
user->fd = fd;
user->all_threads = all_threads;