]> granicus.if.org Git - python/commitdiff
Issue #21119: asyncio: Make sure that socketpair() close sockets on error
authorVictor Stinner <victor.stinner@gmail.com>
Tue, 3 Jun 2014 22:12:28 +0000 (00:12 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Tue, 3 Jun 2014 22:12:28 +0000 (00:12 +0200)
Close the listening socket if sock.bind() raises an exception.

Lib/asyncio/windows_utils.py
Lib/test/test_asyncio/test_windows_utils.py

index 2a196cc76b42e75f3d7da1dd3ef5ebcba3f0b8d0..f7f2f3580adee836b106ec9e706bd48c41d200c7 100644 (file)
@@ -51,23 +51,25 @@ def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
     # We create a connected TCP socket. Note the trick with setblocking(0)
     # that prevents us from having to create a thread.
     lsock = socket.socket(family, type, proto)
-    lsock.bind((host, 0))
-    lsock.listen(1)
-    # On IPv6, ignore flow_info and scope_id
-    addr, port = lsock.getsockname()[:2]
-    csock = socket.socket(family, type, proto)
-    csock.setblocking(False)
     try:
-        csock.connect((addr, port))
-    except (BlockingIOError, InterruptedError):
-        pass
-    except Exception:
+        lsock.bind((host, 0))
+        lsock.listen(1)
+        # On IPv6, ignore flow_info and scope_id
+        addr, port = lsock.getsockname()[:2]
+        csock = socket.socket(family, type, proto)
+        try:
+            csock.setblocking(False)
+            try:
+                csock.connect((addr, port))
+            except (BlockingIOError, InterruptedError):
+                pass
+            ssock, _ = lsock.accept()
+            csock.setblocking(True)
+        except:
+            csock.close()
+            raise
+    finally:
         lsock.close()
-        csock.close()
-        raise
-    ssock, _ = lsock.accept()
-    csock.setblocking(True)
-    lsock.close()
     return (ssock, csock)
 
 
index 9daf4340a4a28dc7571376e747fd12d4c8c7fc54..b1f81da8c2ec58c5f0ba4953ca7622a5c0817215 100644 (file)
@@ -51,6 +51,15 @@ class WinsocketpairTests(unittest.TestCase):
         self.assertRaises(ValueError,
                           windows_utils.socketpair, proto=1)
 
+    @mock.patch('asyncio.windows_utils.socket')
+    def test_winsocketpair_close(self, m_socket):
+        m_socket.AF_INET = socket.AF_INET
+        m_socket.SOCK_STREAM = socket.SOCK_STREAM
+        sock = mock.Mock()
+        m_socket.socket.return_value = sock
+        sock.bind.side_effect = OSError
+        self.assertRaises(OSError, windows_utils.socketpair)
+        self.assertTrue(sock.close.called)
 
 
 class PipeTests(unittest.TestCase):