SF Patch #1062014: AF_UNIX sockets under Linux have a special
abstract namespace that is now fully supported.
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 46468a6..6943080 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -825,6 +825,32 @@
         self.assert_(issubclass(socket.gaierror, socket.error))
         self.assert_(issubclass(socket.timeout, socket.error))
 
+class TestLinuxAbstractNamespace(unittest.TestCase):
+
+    UNIX_PATH_MAX = 108
+
+    def testLinuxAbstractNamespace(self):
+        address = "\x00python-test-hello\x00\xff"
+        s1 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        s1.bind(address)
+        s1.listen(1)
+        s2 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        s2.connect(s1.getsockname())
+        s1.accept()
+        self.assertEqual(s1.getsockname(), address)
+        self.assertEqual(s2.getpeername(), address)
+
+    def testMaxName(self):
+        address = "\x00" + "h" * (self.UNIX_PATH_MAX - 1)
+        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        s.bind(address)
+        self.assertEqual(s.getsockname(), address)
+
+    def testNameOverflow(self):
+        address = "\x00" + "h" * self.UNIX_PATH_MAX
+        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.assertRaises(socket.error, s.bind, address)
+
 
 def test_main():
     tests = [GeneralModuleTests, BasicTCPTest, TCPTimeoutTest, TestExceptions]
@@ -840,6 +866,8 @@
     ])
     if hasattr(socket, "socketpair"):
         tests.append(BasicSocketPairTest)
+    if sys.platform == 'linux2':
+        tests.append(TestLinuxAbstractNamespace)
     test_support.run_unittest(*tests)
 
 if __name__ == "__main__":
diff --git a/Misc/NEWS b/Misc/NEWS
index 3ccd81b..493c9e4 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -80,6 +80,9 @@
 - Bug #1332852: bsddb module minimum BerkeleyDB version raised to 3.3
   as older versions cause excessive test failures.
 
+- Patch #1062014: AF_UNIX sockets under Linux have a special
+  abstract namespace that is now fully supported.
+
 Library
 -------
 
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 93cb8e0..c9dd4a3 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -968,7 +968,18 @@
 	case AF_UNIX:
 	{
 		struct sockaddr_un *a = (struct sockaddr_un *) addr;
-		return PyString_FromString(a->sun_path);
+#ifdef linux
+		if (a->sun_path[0] == 0) {  /* Linux abstract namespace */
+			addrlen -= (sizeof(*a) - sizeof(a->sun_path));
+			return PyString_FromStringAndSize(a->sun_path,
+							  addrlen);
+		}
+		else
+#endif /* linux */
+		{
+			/* regular NULL-terminated string */
+			return PyString_FromString(a->sun_path);
+		}
 	}
 #endif /* AF_UNIX */
 
@@ -1098,14 +1109,28 @@
 		addr = (struct sockaddr_un*)&(s->sock_addr).un;
 		if (!PyArg_Parse(args, "t#", &path, &len))
 			return 0;
-		if (len >= sizeof addr->sun_path) {
-			PyErr_SetString(socket_error,
-					"AF_UNIX path too long");
-			return 0;
+#ifdef linux
+		if (len > 0 && path[0] == 0) {
+			/* Linux abstract namespace extension */
+			if (len > sizeof addr->sun_path) {
+				PyErr_SetString(socket_error,
+						"AF_UNIX path too long");
+				return 0;
+			}
+		}
+		else
+#endif /* linux */
+                {
+			/* regular NULL-terminated string */
+			if (len >= sizeof addr->sun_path) {
+				PyErr_SetString(socket_error,
+						"AF_UNIX path too long");
+				return 0;
+			}
+			addr->sun_path[len] = 0;
 		}
 		addr->sun_family = s->sock_family;
 		memcpy(addr->sun_path, path, len);
-		addr->sun_path[len] = 0;
 		*addr_ret = (struct sockaddr *) addr;
 #if defined(PYOS_OS2)
 		*len_ret = sizeof(*addr);