diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-03-12 14:32:03 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-03-12 14:32:03 (GMT) |
commit | 95bb714ff759312479cf87b1ff6ec0c14c41b328 (patch) | |
tree | 80d61b4f87737f3242a622fd37702be059af6f5b /Modules/faulthandler.c | |
parent | ebaa81f3b1293a5936c72a0261af2a3ea46a3f27 (diff) | |
download | cpython-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.c | 56 |
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; |