]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.7] bpo-39850: Add support for abstract sockets in multiprocessing (GH-18866) ...
authorPablo Galindo <Pablogsal@gmail.com>
Mon, 9 Mar 2020 14:47:50 +0000 (14:47 +0000)
committerGitHub <noreply@github.com>
Mon, 9 Mar 2020 14:47:50 +0000 (14:47 +0000)
(cherry picked from commit 6012f30beff7fa8396718dfb198ccafc333c565b)

Lib/multiprocessing/connection.py
Lib/multiprocessing/forkserver.py
Lib/multiprocessing/util.py
Lib/test/_test_multiprocessing.py
Misc/NEWS.d/next/Library/2020-03-09-01-45-06.bpo-39850.eaJNIE.rst [new file with mode: 0644]

index 1f3ea504fff439337426f8466f25ecff90dce2fb..6b92cf8a128f638168b013961254c0a0e95ca4c0 100644 (file)
@@ -102,7 +102,7 @@ def address_type(address):
         return 'AF_INET'
     elif type(address) is str and address.startswith('\\\\'):
         return 'AF_PIPE'
-    elif type(address) is str:
+    elif type(address) is str or util.is_abstract_socket_namespace(address):
         return 'AF_UNIX'
     else:
         raise ValueError('address type of %r unrecognized' % address)
@@ -587,7 +587,8 @@ class SocketListener(object):
         self._family = family
         self._last_accepted = None
 
-        if family == 'AF_UNIX':
+        if family == 'AF_UNIX' and not util.is_abstract_socket_namespace(address):
+            # Linux abstract socket namespaces do not need to be explicitly unlinked
             self._unlink = util.Finalize(
                 self, os.unlink, args=(address,), exitpriority=0
                 )
index 040b46e66a033019543811aa2a92058181186370..ffd1735848c455f01cfb2e8d550bc5c49ec76188 100644 (file)
@@ -116,7 +116,8 @@ class ForkServer(object):
             with socket.socket(socket.AF_UNIX) as listener:
                 address = connection.arbitrary_address('AF_UNIX')
                 listener.bind(address)
-                os.chmod(address, 0o600)
+                if not util.is_abstract_socket_namespace(address):
+                    os.chmod(address, 0o600)
                 listener.listen()
 
                 # all client processes own the write end of the "alive" pipe;
index 0f9eac7e9fb4dcd2bbaf8f50c9e70abbef2e1e05..f5331abe821fb1045b99b2f234f3623afc61e83b 100644 (file)
@@ -102,6 +102,29 @@ def log_to_stderr(level=None):
     _log_to_stderr = True
     return _logger
 
+
+# Abstract socket support
+
+def _platform_supports_abstract_sockets():
+    if sys.platform == "linux":
+        return True
+    if hasattr(sys, 'getandroidapilevel'):
+        return True
+    return False
+
+
+def is_abstract_socket_namespace(address):
+    if not address:
+        return False
+    if isinstance(address, bytes):
+        return address[0] == 0
+    elif isinstance(address, str):
+        return address[0] == "\0"
+    raise TypeError('address type of {address!r} unrecognized')
+
+
+abstract_sockets_supported = _platform_supports_abstract_sockets()
+
 #
 # Function returning a temp directory which will be removed on exit
 #
index 18947170cbcdc35f5eb9558a8672f3c6d775068d..30ea23da694991efd52d206262a287f05eb3ca8e 100644 (file)
@@ -3140,6 +3140,19 @@ class _TestListener(BaseTestCase):
         if self.TYPE == 'processes':
             self.assertRaises(OSError, l.accept)
 
+    @unittest.skipUnless(util.abstract_sockets_supported,
+                         "test needs abstract socket support")
+    def test_abstract_socket(self):
+        with self.connection.Listener("\0something") as listener:
+            with self.connection.Client(listener.address) as client:
+                with listener.accept() as d:
+                    client.send(1729)
+                    self.assertEqual(d.recv(), 1729)
+
+        if self.TYPE == 'processes':
+            self.assertRaises(OSError, listener.accept)
+
+
 class _TestListenerClient(BaseTestCase):
 
     ALLOWED_TYPES = ('processes', 'threads')
diff --git a/Misc/NEWS.d/next/Library/2020-03-09-01-45-06.bpo-39850.eaJNIE.rst b/Misc/NEWS.d/next/Library/2020-03-09-01-45-06.bpo-39850.eaJNIE.rst
new file mode 100644 (file)
index 0000000..57f98f5
--- /dev/null
@@ -0,0 +1,2 @@
+:mod:`multiprocessing` now supports abstract socket addresses (if abstract sockets
+are supported in the running platform). Patch by Pablo Galindo.