diff -r a1a936a3b2f6 Lib/test/test_devpoll.py --- a/Lib/test/test_devpoll.py Fri Nov 29 18:57:47 2013 +0100 +++ b/Lib/test/test_devpoll.py Sat Nov 30 15:59:58 2013 +0100 @@ -5,6 +5,7 @@ import os import random import select +import signal import sys import unittest from test.support import TESTFN, run_unittest @@ -120,6 +121,25 @@ self.addCleanup(devpoll.close) self.assertEqual(os.get_inheritable(devpoll.fileno()), False) + @unittest.skipUnless(hasattr(signal, 'alarm'), + "Test requires signal.alarm()") + def test_interrupted(self): + # Test that EINTR is silently ignored. + orig_alrm_handler = signal.signal(signal.SIGALRM, lambda *args: None) + self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler) + self.addCleanup(signal.alarm, 0) + + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + + devpoll = select.devpoll() + self.addCleanup(devpoll.close) + devpoll.register(r, select.POLLIN) + + signal.alarm(1) + self.assertFalse(devpoll.poll(3000)) + def test_main(): run_unittest(DevPollTests) diff -r a1a936a3b2f6 Lib/test/test_epoll.py --- a/Lib/test/test_epoll.py Fri Nov 29 18:57:47 2013 +0100 +++ b/Lib/test/test_epoll.py Sat Nov 30 15:59:58 2013 +0100 @@ -24,6 +24,7 @@ import errno import os import select +import signal import socket import time import unittest @@ -255,6 +256,25 @@ self.addCleanup(epoll.close) self.assertEqual(os.get_inheritable(epoll.fileno()), False) + @unittest.skipUnless(hasattr(signal, 'alarm'), + "Test requires signal.alarm()") + def test_interrupted(self): + # Test that EINTR is silently ignored. + orig_alrm_handler = signal.signal(signal.SIGALRM, lambda *args: None) + self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler) + self.addCleanup(signal.alarm, 0) + + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + + epoll = select.epoll() + self.addCleanup(epoll.close) + epoll.register(r, select.EPOLLIN) + + signal.alarm(1) + self.assertFalse(epoll.poll(3)) + def test_main(): support.run_unittest(TestEPoll) diff -r a1a936a3b2f6 Lib/test/test_kqueue.py --- a/Lib/test/test_kqueue.py Fri Nov 29 18:57:47 2013 +0100 +++ b/Lib/test/test_kqueue.py Sat Nov 30 15:59:58 2013 +0100 @@ -4,6 +4,7 @@ import errno import os import select +import signal import socket import sys import time @@ -211,6 +212,27 @@ self.addCleanup(kqueue.close) self.assertEqual(os.get_inheritable(kqueue.fileno()), False) + @unittest.skipUnless(hasattr(signal, 'alarm'), + "Test requires signal.alarm()") + def test_interrupted(self): + # Test that EINTR is silently ignored. + orig_alrm_handler = signal.signal(signal.SIGALRM, lambda *args: None) + self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler) + self.addCleanup(signal.alarm, 0) + + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + + kqueue = select.kqueue() + self.addCleanup(kqueue.close) + ev = select.kevent(r, select.KQ_FILTER_READ, + select.KQ_EV_ADD | select.KQ_EV_ENABLE) + kq.control([ev], 0) + + signal.alarm(1) + self.assertFalse(kqueue.control(None, 4, 3)) + def test_main(): support.run_unittest(TestKQueue) diff -r a1a936a3b2f6 Lib/test/test_poll.py --- a/Lib/test/test_poll.py Fri Nov 29 18:57:47 2013 +0100 +++ b/Lib/test/test_poll.py Sat Nov 30 15:59:58 2013 +0100 @@ -4,6 +4,7 @@ import subprocess import random import select +import signal import _testcapi try: import threading @@ -199,6 +200,24 @@ os.write(w, b'spam') t.join() + @unittest.skipUnless(hasattr(signal, 'alarm'), + "Test requires signal.alarm()") + def test_interrupted(self): + # Test that EINTR is silently ignored. + orig_alrm_handler = signal.signal(signal.SIGALRM, lambda *args: None) + self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler) + self.addCleanup(signal.alarm, 0) + + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + + pollster = select.poll() + pollster.register(r, select.POLLIN) + + signal.alarm(1) + self.assertFalse(pollster.poll(3000)) + def test_main(): run_unittest(PollTests) diff -r a1a936a3b2f6 Lib/test/test_select.py --- a/Lib/test/test_select.py Fri Nov 29 18:57:47 2013 +0100 +++ b/Lib/test/test_select.py Sat Nov 30 15:59:58 2013 +0100 @@ -1,6 +1,7 @@ import errno import os import select +import signal import sys import unittest from test import support @@ -75,6 +76,22 @@ a[:] = [F()] * 10 self.assertEqual(select.select([], a, []), ([], a[:5], [])) + @unittest.skipUnless(hasattr(signal, 'alarm'), + "Test requires signal.alarm()") + def test_interrupted(self): + # Test that EINTR is silently ignored. + orig_alrm_handler = signal.signal(signal.SIGALRM, lambda *args: None) + self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler) + self.addCleanup(signal.alarm, 0) + + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + + signal.alarm(1) + self.assertEqual(([], [], []), select.select([r], [], [], 3)) + + def test_main(): support.run_unittest(SelectTestCase) support.reap_children() diff -r a1a936a3b2f6 Modules/selectmodule.c --- a/Modules/selectmodule.c Fri Nov 29 18:57:47 2013 +0100 +++ b/Modules/selectmodule.c Sat Nov 30 15:59:58 2013 +0100 @@ -283,7 +283,12 @@ } #else if (n < 0) { - PyErr_SetFromErrno(PyExc_OSError); + if (errno == EINTR) { + /* return empty lists */ + ret = Py_BuildValue("NNN", PyList_New(0), PyList_New(0), PyList_New(0)); + } else { + PyErr_SetFromErrno(PyExc_OSError); + } } #endif else { @@ -546,8 +551,13 @@ self->poll_running = 0; if (poll_result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; + if (errno == EINTR) { + /* return an empty list */ + poll_result = 0; + } else { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } } /* build the result list */ @@ -874,8 +884,13 @@ Py_END_ALLOW_THREADS if (poll_result < 0) { - PyErr_SetFromErrno(PyExc_IOError); - return NULL; + if (errno == EINTR) { + /* return an empty list */ + poll_result = 0; + } else { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } } /* build the result list */ @@ -1467,8 +1482,13 @@ nfds = epoll_wait(self->epfd, evs, maxevents, timeout); Py_END_ALLOW_THREADS if (nfds < 0) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; + if (errno == EINTR) { + /* return an empty list */ + nfds = 0; + } else { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } } elist = PyList_New(nfds); @@ -2089,8 +2109,13 @@ Py_END_ALLOW_THREADS if (gotevents == -1) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; + if (errno == EINTR) { + /* return an empty list */ + gotevents = 0; + } else { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } } result = PyList_New(gotevents);