merge
This commit is contained in:
commit
17dd53b464
@ -275,6 +275,57 @@ class WakeupSignalTests(unittest.TestCase):
|
|||||||
|
|
||||||
assert_python_ok('-c', code)
|
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")
|
||||||
|
"""
|
||||||
|
r, w = os.pipe()
|
||||||
|
try:
|
||||||
|
os.write(r, b'x')
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.skipTest("OS doesn't report write() error on the read end of a pipe")
|
||||||
|
finally:
|
||||||
|
os.close(r)
|
||||||
|
os.close(w)
|
||||||
|
|
||||||
|
assert_python_ok('-c', code)
|
||||||
|
|
||||||
def test_wakeup_fd_early(self):
|
def test_wakeup_fd_early(self):
|
||||||
self.check_wakeup("""def test():
|
self.check_wakeup("""def test():
|
||||||
import select
|
import select
|
||||||
|
@ -10,6 +10,10 @@ Projected Release date: 2013-09-08
|
|||||||
Core and Builtins
|
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 #18722: Remove uses of the "register" keyword in C code.
|
||||||
|
|
||||||
- Issue #18667: Add missing "HAVE_FCHOWNAT" symbol to posix._have_functions.
|
- Issue #18667: Add missing "HAVE_FCHOWNAT" symbol to posix._have_functions.
|
||||||
|
@ -175,15 +175,31 @@ checksignals_witharg(void * unused)
|
|||||||
return PyErr_CheckSignals();
|
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
|
static void
|
||||||
trip_signal(int sig_num)
|
trip_signal(int sig_num)
|
||||||
{
|
{
|
||||||
unsigned char byte;
|
unsigned char byte;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
Handlers[sig_num].tripped = 1;
|
Handlers[sig_num].tripped = 1;
|
||||||
if (wakeup_fd != -1) {
|
if (wakeup_fd != -1) {
|
||||||
byte = (unsigned char)sig_num;
|
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)
|
if (is_tripped)
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user