diff -r fbd104359ef8 Lib/test/test_signal.py --- a/Lib/test/test_signal.py Tue Jul 29 23:31:34 2014 +0200 +++ b/Lib/test/test_signal.py Wed Jul 30 00:17:59 2014 +0200 @@ -271,6 +271,9 @@ class WakeupFDTests(unittest.TestCase): self.addCleanup(os.close, r2) self.addCleanup(os.close, w2) + os.set_blocking(w1, False) + os.set_blocking(w2, False) + signal.set_wakeup_fd(w1) self.assertEqual(signal.set_wakeup_fd(w2), w1) self.assertEqual(signal.set_wakeup_fd(-1), w2) @@ -279,10 +282,12 @@ class WakeupFDTests(unittest.TestCase): def test_set_wakeup_fd_socket_result(self): sock1 = socket.socket() self.addCleanup(sock1.close) + sock1.setblocking(False) fd1 = sock1.fileno() sock2 = socket.socket() self.addCleanup(sock2.close) + sock2.setblocking(False) fd2 = sock2.fileno() signal.set_wakeup_fd(fd1) @@ -290,6 +295,26 @@ class WakeupFDTests(unittest.TestCase): self.assertIs(signal.set_wakeup_fd(-1), fd2) self.assertIs(signal.set_wakeup_fd(-1), -1) + # On Windows, files are always blocking and Windows does not provide a + # function to test if a socket is in non-blocking mode. + @unittest.skipIf(sys.platform == "win32", "tests specific to POSIX") + def test_set_wakeup_fd_blocking(self): + rfd, wfd = os.pipe() + self.addCleanup(os.close, rfd) + self.addCleanup(os.close, wfd) + + # fd must be non-blocking + os.set_blocking(wfd, True) + with self.assertRaises(ValueError) as cm: + signal.set_wakeup_fd(wfd) + self.assertEqual(str(cm.exception), + "the fd must be in non-blocking mode") + + # non-blocking is ok + os.set_blocking(wfd, False) + signal.set_wakeup_fd(wfd) + signal.set_wakeup_fd(-1) + @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") class WakeupSignalTests(unittest.TestCase): diff -r fbd104359ef8 Modules/signalmodule.c --- a/Modules/signalmodule.c Tue Jul 29 23:31:34 2014 +0200 +++ b/Modules/signalmodule.c Wed Jul 30 00:17:59 2014 +0200 @@ -561,9 +561,15 @@ signal_set_wakeup_fd(PyObject *self, PyO PyErr_SetFromErrno(PyExc_OSError); return NULL; } + + /* on Windows, a file cannot be set to non-blocking mode */ } - else + else { is_socket = 1; + + /* Windows does not provide a function to test if a socket + is in non-blocking mode */ + } } old_fd = wakeup.fd; @@ -576,6 +582,8 @@ signal_set_wakeup_fd(PyObject *self, PyO return PyLong_FromLong(-1); #else if (fd != -1) { + int blocking; + if (!_PyVerify_fd(fd)) { PyErr_SetString(PyExc_ValueError, "invalid fd"); return NULL; @@ -585,6 +593,15 @@ signal_set_wakeup_fd(PyObject *self, PyO PyErr_SetFromErrno(PyExc_OSError); return NULL; } + + blocking = _Py_get_blocking(fd); + if (blocking < 0) + return NULL; + if (blocking) { + PyErr_SetString(PyExc_ValueError, + "the fd must be in non-blocking mode"); + return NULL; + } } old_fd = wakeup_fd;