diff -r bd5c74def80d Lib/test/test_signal.py --- a/Lib/test/test_signal.py Thu Oct 04 02:43:02 2012 +0200 +++ b/Lib/test/test_signal.py Wed Oct 03 22:56:21 2012 -0300 @@ -9,7 +9,9 @@ import subprocess import traceback import sys, os, time, errno -from test.script_helper import assert_python_ok, spawn_python +from test.script_helper import assert_python_ok, \ + assert_python_failure, \ + spawn_python try: import threading except ImportError: @@ -265,6 +267,43 @@ assert_python_ok('-c', code) + def test_wakeup_read_only_fd(self): + # use a subprocess to have only one thread + code = """if 1: + try: + import fcntl + import sys + import os + import signal + import time + + def handler(signum, frame): + pass + + signal.signal(signal.SIGALRM, handler) + read, write = os.pipe() + for fd in (read, write): + flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) + flags = flags | os.O_NONBLOCK + fcntl.fcntl(fd, fcntl.F_SETFL, flags) + + # set wakeup_fd a read file descriptor to trigger the error + signal.set_wakeup_fd(read) + + signal.alarm(1) + interval = sys.getswitchinterval() + while range(2): + time.sleep(interval) + + os.close(read) + os.close(write) + sys.exit(0) + except ValueError: + sys.exit(-1) + """ + + assert_python_failure('-c', code) + def test_wakeup_fd_early(self): self.check_wakeup("""def test(): import select diff -r bd5c74def80d Modules/signalmodule.c --- a/Modules/signalmodule.c Thu Oct 04 02:43:02 2012 +0200 +++ b/Modules/signalmodule.c Wed Oct 03 22:56:21 2012 -0300 @@ -174,6 +174,11 @@ static int checksignals_witharg(void * unused) { + int error = (int) unused; + if (error == EBADF || error == EPIPE || error == EINVAL) { + PyErr_Format(PyExc_ValueError, "error ocurred waking up fd"); + return NULL; + } return PyErr_CheckSignals(); } @@ -185,7 +190,10 @@ Handlers[sig_num].tripped = 1; if (wakeup_fd != -1) { byte = (unsigned char)sig_num; - write(wakeup_fd, &byte, 1); + if (write(wakeup_fd, &byte, 1) == -1) { + Py_AddPendingCall(checksignals_witharg, errno); + return; + } } if (is_tripped) return;