[Python-checkins] cpython: Issue #22042: signal.set_wakeup_fd(fd) now raises an exception if the file

victor.stinner python-checkins at python.org
Wed Aug 27 12:59:56 CEST 2014


http://hg.python.org/cpython/rev/d984dfe8c34e
changeset:   92251:d984dfe8c34e
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Wed Aug 27 12:59:44 2014 +0200
summary:
  Issue #22042: signal.set_wakeup_fd(fd) now raises an exception if the file
descriptor is in blocking mode.

files:
  Lib/test/test_signal.py |  25 +++++++++++++++++++++++++
  Misc/NEWS               |   3 +++
  Modules/signalmodule.c  |  20 +++++++++++++++++++-
  3 files changed, 47 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
@@ -271,6 +271,9 @@
         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 @@
     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 @@
         self.assertEqual(signal.set_wakeup_fd(-1), fd2)
         self.assertEqual(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 %s must be in non-blocking mode" % wfd)
+
+        # 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 --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -124,6 +124,9 @@
 Library
 -------
 
+- Issue #22042: signal.set_wakeup_fd(fd) now raises an exception if the file
+  descriptor is in blocking mode.
+
 - Issue #16808: inspect.stack() now returns a named tuple instead of a tuple.
   Patch by Daniel Shahaf.
 
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -561,9 +561,15 @@
                 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 @@
         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,16 @@
             PyErr_SetFromErrno(PyExc_OSError);
             return NULL;
         }
+
+        blocking = _Py_get_blocking(fd);
+        if (blocking < 0)
+            return NULL;
+        if (blocking) {
+            PyErr_Format(PyExc_ValueError,
+                         "the fd %i must be in non-blocking mode",
+                         fd);
+            return NULL;
+        }
     }
 
     old_fd = wakeup_fd;

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list