]> granicus.if.org Git - python/commitdiff
bpo-34139: Remove unix datagram socket from FS before binding (GH-8323)
authorQuentin Dawans <github@ovv.wtf>
Tue, 9 Apr 2019 13:40:59 +0000 (15:40 +0200)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 9 Apr 2019 13:40:59 +0000 (06:40 -0700)
https://bugs.python.org/issue34139

Lib/asyncio/base_events.py
Lib/test/test_asyncio/test_base_events.py
Misc/NEWS.d/next/Library/2018-07-18-11-25-34.bpo-34139.tKbmW7.rst [new file with mode: 0644]

index 36fe7e0076c969b0ab8ed7663b8c534e06406d98..9b4b846131de10e5299e231aecdab475cf2a8672 100644 (file)
@@ -20,6 +20,7 @@ import heapq
 import itertools
 import os
 import socket
+import stat
 import subprocess
 import threading
 import time
@@ -1183,6 +1184,19 @@ class BaseEventLoop(events.AbstractEventLoop):
                 for addr in (local_addr, remote_addr):
                     if addr is not None and not isinstance(addr, str):
                         raise TypeError('string is expected')
+
+                if local_addr and local_addr[0] not in (0, '\x00'):
+                    try:
+                        if stat.S_ISSOCK(os.stat(local_addr).st_mode):
+                            os.remove(local_addr)
+                    except FileNotFoundError:
+                        pass
+                    except OSError as err:
+                        # Directory may have permissions only to create socket.
+                        logger.error('Unable to check or remove stale UNIX '
+                                     'socket %r: %r',
+                                     local_addr, err)
+
                 addr_pairs_info = (((family, proto),
                                     (local_addr, remote_addr)), )
             else:
index 53854758a27d4c649d54c83778fe6c9ff3922a46..c245c472996ec3f2889f5a800c8fac75c9b2d737 100644 (file)
@@ -1662,6 +1662,20 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         self.loop.run_until_complete(protocol.done)
         self.assertEqual('CLOSED', protocol.state)
 
+    @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
+    def test_create_datagram_endpoint_existing_sock_unix(self):
+        with test_utils.unix_socket_path() as path:
+            sock = socket.socket(socket.AF_UNIX, type=socket.SOCK_DGRAM)
+            sock.bind(path)
+            sock.close()
+
+            coro = self.loop.create_datagram_endpoint(
+                lambda: MyDatagramProto(create_future=True, loop=self.loop),
+                path, family=socket.AF_UNIX)
+            transport, protocol = self.loop.run_until_complete(coro)
+            transport.close()
+            self.loop.run_until_complete(protocol.done)
+
     def test_create_datagram_endpoint_sock_sockopts(self):
         class FakeSock:
             type = socket.SOCK_DGRAM
diff --git a/Misc/NEWS.d/next/Library/2018-07-18-11-25-34.bpo-34139.tKbmW7.rst b/Misc/NEWS.d/next/Library/2018-07-18-11-25-34.bpo-34139.tKbmW7.rst
new file mode 100644 (file)
index 0000000..44284a7
--- /dev/null
@@ -0,0 +1 @@
+Remove stale unix datagram socket before binding