mirror of
https://github.com/python/cpython.git
synced 2025-11-25 04:34:37 +00:00
SF Patch #1062014: AF_UNIX sockets under Linux have a special
abstract namespace that is now fully supported.
This commit is contained in:
parent
ab012af6ed
commit
a9017c39ce
3 changed files with 62 additions and 6 deletions
|
|
@ -825,6 +825,32 @@ class TestExceptions(unittest.TestCase):
|
||||||
self.assert_(issubclass(socket.gaierror, socket.error))
|
self.assert_(issubclass(socket.gaierror, socket.error))
|
||||||
self.assert_(issubclass(socket.timeout, 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():
|
def test_main():
|
||||||
tests = [GeneralModuleTests, BasicTCPTest, TCPTimeoutTest, TestExceptions]
|
tests = [GeneralModuleTests, BasicTCPTest, TCPTimeoutTest, TestExceptions]
|
||||||
|
|
@ -840,6 +866,8 @@ def test_main():
|
||||||
])
|
])
|
||||||
if hasattr(socket, "socketpair"):
|
if hasattr(socket, "socketpair"):
|
||||||
tests.append(BasicSocketPairTest)
|
tests.append(BasicSocketPairTest)
|
||||||
|
if sys.platform == 'linux2':
|
||||||
|
tests.append(TestLinuxAbstractNamespace)
|
||||||
test_support.run_unittest(*tests)
|
test_support.run_unittest(*tests)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,9 @@ Extension Modules
|
||||||
- Bug #1332852: bsddb module minimum BerkeleyDB version raised to 3.3
|
- Bug #1332852: bsddb module minimum BerkeleyDB version raised to 3.3
|
||||||
as older versions cause excessive test failures.
|
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
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -968,7 +968,18 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
{
|
{
|
||||||
struct sockaddr_un *a = (struct sockaddr_un *) addr;
|
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 */
|
#endif /* AF_UNIX */
|
||||||
|
|
||||||
|
|
@ -1098,14 +1109,28 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
||||||
addr = (struct sockaddr_un*)&(s->sock_addr).un;
|
addr = (struct sockaddr_un*)&(s->sock_addr).un;
|
||||||
if (!PyArg_Parse(args, "t#", &path, &len))
|
if (!PyArg_Parse(args, "t#", &path, &len))
|
||||||
return 0;
|
return 0;
|
||||||
if (len >= sizeof addr->sun_path) {
|
#ifdef linux
|
||||||
PyErr_SetString(socket_error,
|
if (len > 0 && path[0] == 0) {
|
||||||
"AF_UNIX path too long");
|
/* Linux abstract namespace extension */
|
||||||
return 0;
|
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;
|
addr->sun_family = s->sock_family;
|
||||||
memcpy(addr->sun_path, path, len);
|
memcpy(addr->sun_path, path, len);
|
||||||
addr->sun_path[len] = 0;
|
|
||||||
*addr_ret = (struct sockaddr *) addr;
|
*addr_ret = (struct sockaddr *) addr;
|
||||||
#if defined(PYOS_OS2)
|
#if defined(PYOS_OS2)
|
||||||
*len_ret = sizeof(*addr);
|
*len_ret = sizeof(*addr);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue