[Python-checkins] cpython: Issue #16105: When a signal handler fails to write to the file descriptor
antoine.pitrou
python-checkins at python.org
Sat Aug 17 20:33:11 CEST 2013
http://hg.python.org/cpython/rev/e2b234f5bf7d
changeset: 85239:e2b234f5bf7d
parent: 85237:5c091acc799f
user: Antoine Pitrou <solipsis at pitrou.net>
date: Sat Aug 17 20:27:56 2013 +0200
summary:
Issue #16105: When a signal handler fails to write to the file descriptor registered with ``signal.set_wakeup_fd()``, report an exception instead of ignoring the error.
files:
Lib/test/test_signal.py | 41 +++++++++++++++++++++++++++++
Misc/NEWS | 4 ++
Modules/signalmodule.c | 18 ++++++++++++-
3 files changed, 62 insertions(+), 1 deletions(-)
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -275,6 +275,47 @@
assert_python_ok('-c', code)
+ def test_wakeup_write_error(self):
+ # Issue #16105: write() errors in the C signal handler should not
+ # pass silently.
+ # Use a subprocess to have only one thread.
+ code = """if 1:
+ import errno
+ import fcntl
+ import os
+ import signal
+ import sys
+ import time
+ from test.support import captured_stderr
+
+ def handler(signum, frame):
+ 1/0
+
+ signal.signal(signal.SIGALRM, handler)
+ r, w = os.pipe()
+ flags = fcntl.fcntl(r, fcntl.F_GETFL, 0)
+ fcntl.fcntl(r, fcntl.F_SETFL, flags | os.O_NONBLOCK)
+
+ # Set wakeup_fd a read-only file descriptor to trigger the error
+ signal.set_wakeup_fd(r)
+ try:
+ with captured_stderr() as err:
+ signal.alarm(1)
+ time.sleep(5.0)
+ except ZeroDivisionError:
+ # An ignored exception should have been printed out on stderr
+ err = err.getvalue()
+ if ('Exception ignored when trying to write to the signal wakeup fd'
+ not in err):
+ raise AssertionError(err)
+ if ('OSError: [Errno %d]' % errno.EBADF) not in err:
+ raise AssertionError(err)
+ else:
+ raise AssertionError("ZeroDivisionError not raised")
+ """
+
+ assert_python_ok('-c', code)
+
def test_wakeup_fd_early(self):
self.check_wakeup("""def test():
import select
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,10 @@
Core and Builtins
-----------------
+- Issue #16105: When a signal handler fails to write to the file descriptor
+ registered with ``signal.set_wakeup_fd()``, report an exception instead
+ of ignoring the error.
+
- Issue #18722: Remove uses of the "register" keyword in C code.
- Issue #18667: Add missing "HAVE_FCHOWNAT" symbol to posix._have_functions.
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -175,15 +175,31 @@
return PyErr_CheckSignals();
}
+static int
+report_wakeup_error(void *data)
+{
+ int save_errno = errno;
+ errno = (int) (Py_intptr_t) data;
+ PyErr_SetFromErrno(PyExc_OSError);
+ PySys_WriteStderr("Exception ignored when trying to write to the "
+ "signal wakeup fd:\n");
+ PyErr_WriteUnraisable(NULL);
+ errno = save_errno;
+ return 0;
+}
+
static void
trip_signal(int sig_num)
{
unsigned char byte;
+ int rc = 0;
Handlers[sig_num].tripped = 1;
if (wakeup_fd != -1) {
byte = (unsigned char)sig_num;
- write(wakeup_fd, &byte, 1);
+ while ((rc = write(wakeup_fd, &byte, 1)) == -1 && errno == EINTR);
+ if (rc == -1)
+ Py_AddPendingCall(report_wakeup_error, (void *) (Py_intptr_t) errno);
}
if (is_tripped)
return;
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list