From fd7b901e9a73ad851ae16a8dad750148028f5b12 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 30 May 2019 12:44:08 -0300 Subject: [PATCH 01/26] Add methods send_fds, recv_fds to the socket module --- Doc/library/socket.rst | 24 ++++++++++++++++++++++++ Doc/whatsnew/3.8.rst | 5 +++++ Lib/socket.py | 32 +++++++++++++++++++++++++++++++- Lib/test/test_socket.py | 24 ++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index e0dbbb4c0d3201..87cfd0945824f5 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -669,6 +669,30 @@ The following functions all create :ref:`socket objects `. .. versionadded:: 3.3 +.. function:: socket.send_fds(sock, msg, fds) + + :func:`socket.send_fds` sends the list of file descriptors *fds* + over an :const:`AF_UNIX` socket, on systems which support the + :const:`SCM_RIGHTS` mechanism. + + .. availability:: most Unix platforms, possibly others. + + .. versionadded:: 3.8 + + +.. function:: socket.recv_fds(sock, msglen, maxfds) + + On systems which support the :const:`SCM_RIGHTS` mechanism, + :func:`socket.recv_fds` will receive up to *maxfds* file descriptors, + returning the message data and a list containing the descriptors + (while ignoring unexpected conditions such as unrelated control + messages being received). + + .. availability:: most Unix platforms, possibly others. + + .. versionadded:: 3.8 + + .. data:: SocketType This is a Python type object that represents the socket object type. It is the diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 98f0c3474f26ed..3c16f48a499e50 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -560,6 +560,11 @@ The :func:`socket.if_nameindex()`, :func:`socket.if_nametoindex()`, and :func:`socket.if_indextoname()` functions have been implemented on Windows. (Contributed by Zackery Spytz in :issue:`37007`.) +Added :func:`socket.send_fds()` and :func:`socket.recv_fds` to send and +receive a file descriptor from the socket. +(Contributed by Joannah Nanjekye in :issue:`28724`.) + + shlex ---------- diff --git a/Lib/socket.py b/Lib/socket.py index 0dd8ec70e168aa..c7275a987806aa 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -12,6 +12,8 @@ socket() -- create a new socket object socketpair() -- create a pair of new socket objects [*] fromfd() -- create a socket object from an open file descriptor [*] +send_fds() -- Send file descriptor to the socket. +recv_fds() -- Recieve file descriptor from the socket. fromshare() -- create a socket object from data received from socket.share() [*] gethostname() -- return the current hostname gethostbyname() -- map a hostname to its IP number @@ -49,7 +51,7 @@ import _socket from _socket import * -import os, sys, io, selectors +import os, sys, io, selectors, array from enum import IntEnum, IntFlag try: @@ -463,6 +465,34 @@ def fromfd(fd, family, type, proto=0): nfd = dup(fd) return socket(family, type, proto, nfd) +if hasattr(_socket.socket, "sendmsg"): + def send_fds(sock, msg, fds): + """ send_fds(sock, msg, fds) -> socket object + + Send the list of file descriptors fds over an AF_UNIX socket. + """ + return sock.sendmsg([msg], [(_socket.SOL_SOCKET, + _socket.SCM_RIGHTS, array.array("i", fds))]) + __all__.append("send_fds") + +if hasattr(_socket.socket, "recvmsg"): + def recv_fds(sock, msglen, maxfds): + """ recv_fds(sock, msglen, maxfds) -> (socket object, socket object) + + receive up to maxfds file descriptors returning the message + data and a list containing the descriptors. + """ + # Array of ints + fds = array.array("i") + msg, ancdata, flags, addr = sock.recvmsg(msglen, + _socket.CMSG_LEN(maxfds * fds.itemsize)) + for cmsg_level, cmsg_type, cmsg_data in ancdata: + if (cmsg_level == _socket.SOL_SOCKET and cmsg_type == _socket.SCM_RIGHTS): + # Append data, ignoring any truncated integers at the end. + fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + return msg, list(fds) + __all__.append("recv_fds") + if hasattr(_socket.socket, "share"): def fromshare(info): """ fromshare(info) -> socket object diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 74662cfeb327af..fd92fb8b6d280a 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2275,6 +2275,30 @@ def testFromFd(self): def _testFromFd(self): self.serv_conn.send(MSG) + @requireAttrs(socket.socket, "sendmsg") + @requireAttrs(socket, "AF_UNIX") + @requireAttrs(socket, "SCM_RIGHTS") + def testSendAndRecvFds(self): + fds = [] + # create two new file descriptors. + for i in range(2): + fd, path = tempfile.mkstemp() + self.addCleanup(os.unlink, path) + self.addCleanup(os.close, fd) + os.write(fd, str(i).encode()) + fds.append(fd) + f = self.cli_conn.detach() + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, fileno=f) + self.addCleanup(sock.close) + with sock: + socket.send_fds(sock, MSG, fds) + msg, fds_list = socket.recv_fds(sock, len(MSG), 1024) + self.assertEqual(msg, MSG) + + @testSendAndRecvFds.client_skip + def _testSendAndRecvFds(self): + self.serv_conn.send(MSG) + def testDup(self): # Testing dup() sock = self.cli_conn.dup() From 2558c5d71f8a268283b28a2ea06f10d8851b1dff Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" Date: Thu, 30 May 2019 15:51:47 +0000 Subject: [PATCH 02/26] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst diff --git a/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst b/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst new file mode 100644 index 00000000000000..5746ebde8c84c5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst @@ -0,0 +1,2 @@ +The socket module now has the :func:`socket.send_fds()` and :func:`socket.recv.fds()` functions. +Contributed by Joannah Nanjekye and Shinya Okano . \ No newline at end of file From dfdeb76fb45be660680f206273a6db388f6dfd33 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 30 May 2019 13:13:21 -0300 Subject: [PATCH 03/26] Fix tests on MacOS --- Lib/test/test_socket.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index fd92fb8b6d280a..1111cf4da6c9e5 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2278,6 +2278,7 @@ def _testFromFd(self): @requireAttrs(socket.socket, "sendmsg") @requireAttrs(socket, "AF_UNIX") @requireAttrs(socket, "SCM_RIGHTS") + @requireAttrs(socket, "SOL_SOCKET") def testSendAndRecvFds(self): fds = [] # create two new file descriptors. From cc6973cbcf44dd3c5514cf52ef65d327f8b59b72 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 30 May 2019 13:37:16 -0300 Subject: [PATCH 04/26] Attempt to fix MacOS --- Lib/test/test_socket.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 1111cf4da6c9e5..37151befe1eed4 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2276,9 +2276,7 @@ def _testFromFd(self): self.serv_conn.send(MSG) @requireAttrs(socket.socket, "sendmsg") - @requireAttrs(socket, "AF_UNIX") - @requireAttrs(socket, "SCM_RIGHTS") - @requireAttrs(socket, "SOL_SOCKET") + @unittest.skipUnless(_socket is not None, 'need _socket module') def testSendAndRecvFds(self): fds = [] # create two new file descriptors. From 5050e5923c505d68694093645f704ffa264ea39f Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 30 May 2019 13:59:38 -0300 Subject: [PATCH 05/26] MacOS fix --- Lib/test/test_socket.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 37151befe1eed4..ce527d2b5316e6 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2276,6 +2276,7 @@ def _testFromFd(self): self.serv_conn.send(MSG) @requireAttrs(socket.socket, "sendmsg") + @requireAttrs(socket, "AF_UNIX") @unittest.skipUnless(_socket is not None, 'need _socket module') def testSendAndRecvFds(self): fds = [] From fe8ff1a754f7f7d64c58aaaba41a8218c50aff92 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 30 May 2019 14:25:38 -0300 Subject: [PATCH 06/26] Mac OS fix --- Lib/test/test_socket.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index ce527d2b5316e6..2299185ec58f84 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2277,7 +2277,8 @@ def _testFromFd(self): @requireAttrs(socket.socket, "sendmsg") @requireAttrs(socket, "AF_UNIX") - @unittest.skipUnless(_socket is not None, 'need _socket module') + @unittest.skipUnless(_socket.SOL_SOCKET is not None, 'need _socket.SOL_SOCKET module') + @unittest.skipUnless(_socket.SCM_RIGHTS is not None, 'need _socket.SCM_RIGHTS module') def testSendAndRecvFds(self): fds = [] # create two new file descriptors. From e98918fb347da98bf8d014fec6fd4c8a1e214cf5 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 30 May 2019 14:40:18 -0300 Subject: [PATCH 07/26] fix Mac OS --- Lib/test/test_socket.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 2299185ec58f84..c7139c6957d43c 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2276,9 +2276,8 @@ def _testFromFd(self): self.serv_conn.send(MSG) @requireAttrs(socket.socket, "sendmsg") - @requireAttrs(socket, "AF_UNIX") - @unittest.skipUnless(_socket.SOL_SOCKET is not None, 'need _socket.SOL_SOCKET module') - @unittest.skipUnless(_socket.SCM_RIGHTS is not None, 'need _socket.SCM_RIGHTS module') + @requireAttrs(socket, "SCM_RIGHTS") + @requireAttrs(socket, "SOL_SOCKET") def testSendAndRecvFds(self): fds = [] # create two new file descriptors. From c3fcd6f5dadb44cc5500d6667c7cf2d38e52c7b0 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 30 May 2019 15:06:39 -0300 Subject: [PATCH 08/26] Attempt again --- Lib/test/test_socket.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index c7139c6957d43c..6b38d282210217 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2276,8 +2276,8 @@ def _testFromFd(self): self.serv_conn.send(MSG) @requireAttrs(socket.socket, "sendmsg") - @requireAttrs(socket, "SCM_RIGHTS") - @requireAttrs(socket, "SOL_SOCKET") + @requireAttrs(socket, "AF_UNIX") + @unittest.skipIf(sys.platform == 'darwin', 'test not working for MacOSX') def testSendAndRecvFds(self): fds = [] # create two new file descriptors. From d497c15c3732d6315899a2d3253fe24e21beba8d Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Thu, 30 May 2019 21:39:09 -0300 Subject: [PATCH 09/26] keep the function signatures close to the original ones --- Doc/library/socket.rst | 4 ++-- Lib/socket.py | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 87cfd0945824f5..e050c19f465631 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -669,7 +669,7 @@ The following functions all create :ref:`socket objects `. .. versionadded:: 3.3 -.. function:: socket.send_fds(sock, msg, fds) +.. function:: socket.send_fds(sock, buffers, fds[, flags[, address]]) :func:`socket.send_fds` sends the list of file descriptors *fds* over an :const:`AF_UNIX` socket, on systems which support the @@ -680,7 +680,7 @@ The following functions all create :ref:`socket objects `. .. versionadded:: 3.8 -.. function:: socket.recv_fds(sock, msglen, maxfds) +.. function:: socket.recv_fds(sock, bufsize, maxfds[, flags]) On systems which support the :const:`SCM_RIGHTS` mechanism, :func:`socket.recv_fds` will receive up to *maxfds* file descriptors, diff --git a/Lib/socket.py b/Lib/socket.py index c7275a987806aa..2dc53303d4addd 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -465,26 +465,28 @@ def fromfd(fd, family, type, proto=0): nfd = dup(fd) return socket(family, type, proto, nfd) +_GLOBAL_DEFAULT_MAXFDS = object() + if hasattr(_socket.socket, "sendmsg"): - def send_fds(sock, msg, fds): - """ send_fds(sock, msg, fds) -> socket object + def send_fds(sock, buffers=None, fds=[], flags=[], address=None): + """ send_fds(sock, buffers, fds[, flags[, address]]) -> socket object Send the list of file descriptors fds over an AF_UNIX socket. """ - return sock.sendmsg([msg], [(_socket.SOL_SOCKET, + return sock.sendmsg([buffers], [(_socket.SOL_SOCKET, _socket.SCM_RIGHTS, array.array("i", fds))]) __all__.append("send_fds") if hasattr(_socket.socket, "recvmsg"): - def recv_fds(sock, msglen, maxfds): - """ recv_fds(sock, msglen, maxfds) -> (socket object, socket object) + def recv_fds(sock, bufsize=0, maxfds=_GLOBAL_DEFAULT_MAXFDS, flags=0): + """ recv_fds(sock, bufsize, maxfds[, flags]) -> (socket object, socket object) receive up to maxfds file descriptors returning the message data and a list containing the descriptors. """ # Array of ints fds = array.array("i") - msg, ancdata, flags, addr = sock.recvmsg(msglen, + msg, ancdata, flags, addr = sock.recvmsg(bufsize, _socket.CMSG_LEN(maxfds * fds.itemsize)) for cmsg_level, cmsg_type, cmsg_data in ancdata: if (cmsg_level == _socket.SOL_SOCKET and cmsg_type == _socket.SCM_RIGHTS): From 035845a39f3342b6644ebf379561eefaa4f9c960 Mon Sep 17 00:00:00 2001 From: nanjekyejoannah Date: Fri, 31 May 2019 14:51:44 -0300 Subject: [PATCH 10/26] make return types consistent --- Lib/socket.py | 8 ++++---- Lib/test/test_socket.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/socket.py b/Lib/socket.py index 2dc53303d4addd..b6a5225756caff 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -468,17 +468,17 @@ def fromfd(fd, family, type, proto=0): _GLOBAL_DEFAULT_MAXFDS = object() if hasattr(_socket.socket, "sendmsg"): - def send_fds(sock, buffers=None, fds=[], flags=[], address=None): + def send_fds(sock, buffers, fds, flags=0, address=None): """ send_fds(sock, buffers, fds[, flags[, address]]) -> socket object Send the list of file descriptors fds over an AF_UNIX socket. """ - return sock.sendmsg([buffers], [(_socket.SOL_SOCKET, + return sock.sendmsg(buffers, [(_socket.SOL_SOCKET, _socket.SCM_RIGHTS, array.array("i", fds))]) __all__.append("send_fds") if hasattr(_socket.socket, "recvmsg"): - def recv_fds(sock, bufsize=0, maxfds=_GLOBAL_DEFAULT_MAXFDS, flags=0): + def recv_fds(sock, bufsize, maxfds, flags=0): """ recv_fds(sock, bufsize, maxfds[, flags]) -> (socket object, socket object) receive up to maxfds file descriptors returning the message @@ -492,7 +492,7 @@ def recv_fds(sock, bufsize=0, maxfds=_GLOBAL_DEFAULT_MAXFDS, flags=0): if (cmsg_level == _socket.SOL_SOCKET and cmsg_type == _socket.SCM_RIGHTS): # Append data, ignoring any truncated integers at the end. fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) - return msg, list(fds) + return msg, list(fds), flags, addr __all__.append("recv_fds") if hasattr(_socket.socket, "share"): diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 6b38d282210217..19b5d32cc91fd7 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2291,8 +2291,8 @@ def testSendAndRecvFds(self): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, fileno=f) self.addCleanup(sock.close) with sock: - socket.send_fds(sock, MSG, fds) - msg, fds_list = socket.recv_fds(sock, len(MSG), 1024) + socket.send_fds(sock, [MSG], fds) + msg, fds_list, flags, addr = socket.recv_fds(sock, len(MSG), 1024) self.assertEqual(msg, MSG) @testSendAndRecvFds.client_skip From e6d22e0afa58df6fccc2f17c3ec3642b0e19f789 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Sat, 1 Jun 2019 19:18:32 -0300 Subject: [PATCH 11/26] Fix freebsd --- Lib/test/test_socket.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 19b5d32cc91fd7..5f279ab08a3853 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2278,6 +2278,7 @@ def _testFromFd(self): @requireAttrs(socket.socket, "sendmsg") @requireAttrs(socket, "AF_UNIX") @unittest.skipIf(sys.platform == 'darwin', 'test not working for MacOSX') + @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd', 'gnukfreebsd')), 'test not working for freebsd') def testSendAndRecvFds(self): fds = [] # create two new file descriptors. From f84d6db8b69dbfee868c2408d1a17aa3f548ee23 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Mon, 3 Jun 2019 15:37:40 -0300 Subject: [PATCH 12/26] Remove unused global sentinel . --- Lib/socket.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/socket.py b/Lib/socket.py index b6a5225756caff..ac07e6f5176051 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -465,8 +465,6 @@ def fromfd(fd, family, type, proto=0): nfd = dup(fd) return socket(family, type, proto, nfd) -_GLOBAL_DEFAULT_MAXFDS = object() - if hasattr(_socket.socket, "sendmsg"): def send_fds(sock, buffers, fds, flags=0, address=None): """ send_fds(sock, buffers, fds[, flags[, address]]) -> socket object From 07b05dc6ad83c8bef68a5e0667c1b2ff16dfb0d2 Mon Sep 17 00:00:00 2001 From: Joannah nanjekye Date: Thu, 6 Jun 2019 12:06:12 -0300 Subject: [PATCH 13/26] Update documentation --- Doc/library/socket.rst | 46 +++++++++---------- Lib/socket.py | 3 +- .../2019-05-30-15-51-42.bpo-28724.34TrS8.rst | 2 +- 3 files changed, 25 insertions(+), 26 deletions(-) mode change 100644 => 100755 Doc/library/socket.rst mode change 100644 => 100755 Lib/socket.py mode change 100644 => 100755 Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst old mode 100644 new mode 100755 index e050c19f465631..68b352a471ebf8 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -669,30 +669,6 @@ The following functions all create :ref:`socket objects `. .. versionadded:: 3.3 -.. function:: socket.send_fds(sock, buffers, fds[, flags[, address]]) - - :func:`socket.send_fds` sends the list of file descriptors *fds* - over an :const:`AF_UNIX` socket, on systems which support the - :const:`SCM_RIGHTS` mechanism. - - .. availability:: most Unix platforms, possibly others. - - .. versionadded:: 3.8 - - -.. function:: socket.recv_fds(sock, bufsize, maxfds[, flags]) - - On systems which support the :const:`SCM_RIGHTS` mechanism, - :func:`socket.recv_fds` will receive up to *maxfds* file descriptors, - returning the message data and a list containing the descriptors - (while ignoring unexpected conditions such as unrelated control - messages being received). - - .. availability:: most Unix platforms, possibly others. - - .. versionadded:: 3.8 - - .. data:: SocketType This is a Python type object that represents the socket object type. It is the @@ -1588,6 +1564,28 @@ to sockets. .. versionadded:: 3.6 +.. method:: socket.send_fds(sock, buffers, fds[, flags[, address]]) + + Send the list of file descriptors *fds* over an :const:`AF_UNIX` socket. + Consult :meth:`sendmsg` for the documentation of these parameters. + + .. availability:: Unix supporting :meth:socket.socket.sendmsg and :const:SCM_RIGHTS mechanism. + + .. versionadded:: 3.9 + +.. method:: socket.recv_fds(sock, bufsize, maxfds[, flags]) + + Receive up to *maxfds* file descriptors. Return (msg, list(fds), flags, addr). Consult + :meth:`recvmsg` for the documentation of these parameters. + + .. availability:: Unix supporting :meth:socket.socket.sendmsg and :const:SCM_RIGHTS mechanism. + + .. versionadded:: 3.9 + + .. note:: + + Any truncated integers at the end are ignored. + .. method:: socket.sendfile(file, offset=0, count=None) Send a file until EOF is reached by using high-performance diff --git a/Lib/socket.py b/Lib/socket.py old mode 100644 new mode 100755 index ac07e6f5176051..302555ec69f932 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -489,7 +489,8 @@ def recv_fds(sock, bufsize, maxfds, flags=0): for cmsg_level, cmsg_type, cmsg_data in ancdata: if (cmsg_level == _socket.SOL_SOCKET and cmsg_type == _socket.SCM_RIGHTS): # Append data, ignoring any truncated integers at the end. - fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + fds.frombytes(cmsg_data[: + len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) return msg, list(fds), flags, addr __all__.append("recv_fds") diff --git a/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst b/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst old mode 100644 new mode 100755 index 5746ebde8c84c5..e4d817850c6d47 --- a/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst +++ b/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst @@ -1,2 +1,2 @@ -The socket module now has the :func:`socket.send_fds()` and :func:`socket.recv.fds()` functions. +The socket module now has the :meth:`socket.send_fds` and :meth:`socket.recv.fds` methods. Contributed by Joannah Nanjekye and Shinya Okano . \ No newline at end of file From 8b96493c4b3e56c2350a02d3442319ac464e1e06 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Thu, 6 Jun 2019 12:28:45 -0300 Subject: [PATCH 14/26] Fix docs --- Doc/library/socket.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 68b352a471ebf8..bb281356f1e46f 100755 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1569,7 +1569,7 @@ to sockets. Send the list of file descriptors *fds* over an :const:`AF_UNIX` socket. Consult :meth:`sendmsg` for the documentation of these parameters. - .. availability:: Unix supporting :meth:socket.socket.sendmsg and :const:SCM_RIGHTS mechanism. + .. availability:: Unix supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. .. versionadded:: 3.9 @@ -1578,7 +1578,7 @@ to sockets. Receive up to *maxfds* file descriptors. Return (msg, list(fds), flags, addr). Consult :meth:`recvmsg` for the documentation of these parameters. - .. availability:: Unix supporting :meth:socket.socket.sendmsg and :const:SCM_RIGHTS mechanism. + .. availability:: Unix supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. .. versionadded:: 3.9 From 7c46e7ad2ee093eacd63c0e625898b4de72a4c04 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Thu, 6 Jun 2019 13:27:07 -0300 Subject: [PATCH 15/26] Update Doc/library/socket.rst Co-Authored-By: Victor Stinner --- Doc/library/socket.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index bb281356f1e46f..5d760fcb500250 100755 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1575,7 +1575,7 @@ to sockets. .. method:: socket.recv_fds(sock, bufsize, maxfds[, flags]) - Receive up to *maxfds* file descriptors. Return (msg, list(fds), flags, addr). Consult + Receive up to *maxfds* file descriptors. Return ``(msg, list(fds), flags, addr)``. Consult :meth:`recvmsg` for the documentation of these parameters. .. availability:: Unix supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. From 2c32da1321c10070afedcc26cfb10fe7a51009c1 Mon Sep 17 00:00:00 2001 From: Joannah nanjekye Date: Thu, 13 Jun 2019 12:18:17 -0300 Subject: [PATCH 16/26] Add Victor's test and update docs --- Doc/whatsnew/3.8.rst | 4 - Doc/whatsnew/3.9.rst | 123 ++++++++++++++++++ Lib/test/test_socket.py | 43 ++++++ .../2019-05-30-15-51-42.bpo-28724.34TrS8.rst | 2 +- 4 files changed, 167 insertions(+), 5 deletions(-) mode change 100644 => 100755 Doc/whatsnew/3.8.rst create mode 100755 Doc/whatsnew/3.9.rst mode change 100644 => 100755 Lib/test/test_socket.py diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst old mode 100644 new mode 100755 index 3c16f48a499e50..ff840c6ac8f7c3 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -560,10 +560,6 @@ The :func:`socket.if_nameindex()`, :func:`socket.if_nametoindex()`, and :func:`socket.if_indextoname()` functions have been implemented on Windows. (Contributed by Zackery Spytz in :issue:`37007`.) -Added :func:`socket.send_fds()` and :func:`socket.recv_fds` to send and -receive a file descriptor from the socket. -(Contributed by Joannah Nanjekye in :issue:`28724`.) - shlex ---------- diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst new file mode 100755 index 00000000000000..5df8b4e1f70326 --- /dev/null +++ b/Doc/whatsnew/3.9.rst @@ -0,0 +1,123 @@ +**************************** + What's New In Python 3.9 +**************************** + +:Release: |release| +:Date: |today| + +.. Rules for maintenance: + + * Anyone can add text to this document. Do not spend very much time + on the wording of your changes, because your text will probably + get rewritten to some degree. + + * The maintainer will go through Misc/NEWS periodically and add + changes; it's therefore more important to add your changes to + Misc/NEWS than to this file. + + * This is not a complete list of every single change; completeness + is the purpose of Misc/NEWS. Some changes I consider too small + or esoteric to include. If such a change is added to the text, + I'll just remove it. (This is another reason you shouldn't spend + too much time on writing your addition.) + + * If you want to draw your new text to the attention of the + maintainer, add 'XXX' to the beginning of the paragraph or + section. + + * It's OK to just add a fragmentary note about a change. For + example: "XXX Describe the transmogrify() function added to the + socket module." The maintainer will research the change and + write the necessary text. + + * You can comment out your additions if you like, but it's not + necessary (especially when a final release is some months away). + + * Credit the author of a patch or bugfix. Just the name is + sufficient; the e-mail address isn't necessary. + + * It's helpful to add the bug/patch number as a comment: + + XXX Describe the transmogrify() function added to the socket + module. + (Contributed by P.Y. Developer in :issue:`12345`.) + + This saves the maintainer the effort of going through the Mercurial log + when researching a change. + +This article explains the new features in Python 3.9, compared to 3.8. + +For full details, see the :source:`Misc/NEWS` file. + +.. note:: + + Prerelease users should be aware that this document is currently in draft + form. It will be updated substantially as Python 3.9 moves towards release, + so it's worth checking back even after reading earlier versions. + + +Summary -- Release highlights +============================= + +.. This section singles out the most important changes in Python 3.9. + Brevity is key. + + +.. PEP-sized items next. + + + +New Features +============ + + + +Other Language Changes +====================== + + + +New Modules +=========== + +* None yet. + + +Improved Modules +================ + + +socket +------ + +Added :func:`socket.send_fds()` and :func:`socket.recv_fds` to send and +receive a file descriptor from the socket. +(Contributed by Joannah Nanjekye and Victor Stinner in :issue:`28724`.) + + +Optimizations +============= + + +Build and C API Changes +======================= + + + +Deprecated +========== + + + +Removed +======= + + + +Porting to Python 3.9 +===================== + +This section lists previously described changes and other bugfixes +that may require changes to your code. + + diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py old mode 100644 new mode 100755 index 5f279ab08a3853..160e053c4391fc --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6279,5 +6279,48 @@ def test_main(): support.run_unittest(*tests) support.threading_cleanup(*thread_info) + +@requireAttrs(socket, "send_fds") +@requireAttrs(socket, "recv_fds") +@requireAttrs(socket, "AF_UNIX") +class SendRecvFdsTests(unittest.TestCase): + @unittest.skipIf(sys.platform == 'darwin', 'test not working for MacOSX') + def testSendAndRecvFds(self): + def close_pipes(pipes): + for fd1, fd2 in pipes: + os.close(fd1) + os.close(fd2) + + def close_fds(fds): + for fd in fds: + os.close(fd) + + # send 10 file descriptors + pipes = [os.pipe() for _ in range(10)] + self.addCleanup(close_pipes, pipes) + fds = [fd2 for fd1, fd2 in pipes] + + # use a UNIX socket pair to exchange file descriptors locally + sock1, sock2 = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM) + with sock1, sock2: + socket.send_fds(sock1, [MSG], fds) + # request more data and file descriptors than expected + msg, fds2, flags, addr = socket.recv_fds(sock2, len(MSG) * 2, len(fds) * 2) + self.addCleanup(close_fds, fds2) + + self.assertEqual(msg, MSG) + self.assertEqual(len(fds2), len(fds)) + self.assertEqual(flags, 0) + # don't test addr + + # test that file descriptors are connected + for index, fds in enumerate(pipes): + fd1, fd2 = fds + os.write(fd1, str(index).encode()) + + for index, fd in enumerate(fds2): + data = os.read(fd, 100) + self.assertEqual(data, str(index).encode()) + if __name__ == "__main__": test_main() diff --git a/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst b/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst index e4d817850c6d47..499b88010d4e65 100755 --- a/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst +++ b/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst @@ -1,2 +1,2 @@ The socket module now has the :meth:`socket.send_fds` and :meth:`socket.recv.fds` methods. -Contributed by Joannah Nanjekye and Shinya Okano . \ No newline at end of file +Contributed by Joannah Nanjekye, Shinya Okano and Victor Stinner. \ No newline at end of file From 75bffbcc0d4d93a82cf44d9266e77a65ad551ca5 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Thu, 13 Jun 2019 12:21:35 -0300 Subject: [PATCH 17/26] no need for new file --- Doc/whatsnew/3.9.rst | 123 ------------------------------------------- 1 file changed, 123 deletions(-) delete mode 100755 Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst deleted file mode 100755 index 5df8b4e1f70326..00000000000000 --- a/Doc/whatsnew/3.9.rst +++ /dev/null @@ -1,123 +0,0 @@ -**************************** - What's New In Python 3.9 -**************************** - -:Release: |release| -:Date: |today| - -.. Rules for maintenance: - - * Anyone can add text to this document. Do not spend very much time - on the wording of your changes, because your text will probably - get rewritten to some degree. - - * The maintainer will go through Misc/NEWS periodically and add - changes; it's therefore more important to add your changes to - Misc/NEWS than to this file. - - * This is not a complete list of every single change; completeness - is the purpose of Misc/NEWS. Some changes I consider too small - or esoteric to include. If such a change is added to the text, - I'll just remove it. (This is another reason you shouldn't spend - too much time on writing your addition.) - - * If you want to draw your new text to the attention of the - maintainer, add 'XXX' to the beginning of the paragraph or - section. - - * It's OK to just add a fragmentary note about a change. For - example: "XXX Describe the transmogrify() function added to the - socket module." The maintainer will research the change and - write the necessary text. - - * You can comment out your additions if you like, but it's not - necessary (especially when a final release is some months away). - - * Credit the author of a patch or bugfix. Just the name is - sufficient; the e-mail address isn't necessary. - - * It's helpful to add the bug/patch number as a comment: - - XXX Describe the transmogrify() function added to the socket - module. - (Contributed by P.Y. Developer in :issue:`12345`.) - - This saves the maintainer the effort of going through the Mercurial log - when researching a change. - -This article explains the new features in Python 3.9, compared to 3.8. - -For full details, see the :source:`Misc/NEWS` file. - -.. note:: - - Prerelease users should be aware that this document is currently in draft - form. It will be updated substantially as Python 3.9 moves towards release, - so it's worth checking back even after reading earlier versions. - - -Summary -- Release highlights -============================= - -.. This section singles out the most important changes in Python 3.9. - Brevity is key. - - -.. PEP-sized items next. - - - -New Features -============ - - - -Other Language Changes -====================== - - - -New Modules -=========== - -* None yet. - - -Improved Modules -================ - - -socket ------- - -Added :func:`socket.send_fds()` and :func:`socket.recv_fds` to send and -receive a file descriptor from the socket. -(Contributed by Joannah Nanjekye and Victor Stinner in :issue:`28724`.) - - -Optimizations -============= - - -Build and C API Changes -======================= - - - -Deprecated -========== - - - -Removed -======= - - - -Porting to Python 3.9 -===================== - -This section lists previously described changes and other bugfixes -that may require changes to your code. - - From ba29ca20dea37920475c664666952b7ddbd14497 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Thu, 13 Jun 2019 12:22:21 -0300 Subject: [PATCH 18/26] Update 3.8.rst --- Doc/whatsnew/3.8.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index ff840c6ac8f7c3..98f0c3474f26ed 100755 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -560,7 +560,6 @@ The :func:`socket.if_nameindex()`, :func:`socket.if_nametoindex()`, and :func:`socket.if_indextoname()` functions have been implemented on Windows. (Contributed by Zackery Spytz in :issue:`37007`.) - shlex ---------- From 83e422dda30dd810c7f4df0db892c275d3e3101b Mon Sep 17 00:00:00 2001 From: Joannah nanjekye Date: Thu, 13 Jun 2019 12:49:40 -0300 Subject: [PATCH 19/26] update 3.9.rst --- Doc/whatsnew/3.9.rst | 123 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100755 Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst new file mode 100755 index 00000000000000..5df8b4e1f70326 --- /dev/null +++ b/Doc/whatsnew/3.9.rst @@ -0,0 +1,123 @@ +**************************** + What's New In Python 3.9 +**************************** + +:Release: |release| +:Date: |today| + +.. Rules for maintenance: + + * Anyone can add text to this document. Do not spend very much time + on the wording of your changes, because your text will probably + get rewritten to some degree. + + * The maintainer will go through Misc/NEWS periodically and add + changes; it's therefore more important to add your changes to + Misc/NEWS than to this file. + + * This is not a complete list of every single change; completeness + is the purpose of Misc/NEWS. Some changes I consider too small + or esoteric to include. If such a change is added to the text, + I'll just remove it. (This is another reason you shouldn't spend + too much time on writing your addition.) + + * If you want to draw your new text to the attention of the + maintainer, add 'XXX' to the beginning of the paragraph or + section. + + * It's OK to just add a fragmentary note about a change. For + example: "XXX Describe the transmogrify() function added to the + socket module." The maintainer will research the change and + write the necessary text. + + * You can comment out your additions if you like, but it's not + necessary (especially when a final release is some months away). + + * Credit the author of a patch or bugfix. Just the name is + sufficient; the e-mail address isn't necessary. + + * It's helpful to add the bug/patch number as a comment: + + XXX Describe the transmogrify() function added to the socket + module. + (Contributed by P.Y. Developer in :issue:`12345`.) + + This saves the maintainer the effort of going through the Mercurial log + when researching a change. + +This article explains the new features in Python 3.9, compared to 3.8. + +For full details, see the :source:`Misc/NEWS` file. + +.. note:: + + Prerelease users should be aware that this document is currently in draft + form. It will be updated substantially as Python 3.9 moves towards release, + so it's worth checking back even after reading earlier versions. + + +Summary -- Release highlights +============================= + +.. This section singles out the most important changes in Python 3.9. + Brevity is key. + + +.. PEP-sized items next. + + + +New Features +============ + + + +Other Language Changes +====================== + + + +New Modules +=========== + +* None yet. + + +Improved Modules +================ + + +socket +------ + +Added :func:`socket.send_fds()` and :func:`socket.recv_fds` to send and +receive a file descriptor from the socket. +(Contributed by Joannah Nanjekye and Victor Stinner in :issue:`28724`.) + + +Optimizations +============= + + +Build and C API Changes +======================= + + + +Deprecated +========== + + + +Removed +======= + + + +Porting to Python 3.9 +===================== + +This section lists previously described changes and other bugfixes +that may require changes to your code. + + From 910461b8222c5efd170f78ca926d1033e7abf723 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Thu, 13 Jun 2019 12:54:03 -0300 Subject: [PATCH 20/26] Delete 3.9.rst --- Doc/whatsnew/3.9.rst | 123 ------------------------------------------- 1 file changed, 123 deletions(-) delete mode 100755 Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst deleted file mode 100755 index 5df8b4e1f70326..00000000000000 --- a/Doc/whatsnew/3.9.rst +++ /dev/null @@ -1,123 +0,0 @@ -**************************** - What's New In Python 3.9 -**************************** - -:Release: |release| -:Date: |today| - -.. Rules for maintenance: - - * Anyone can add text to this document. Do not spend very much time - on the wording of your changes, because your text will probably - get rewritten to some degree. - - * The maintainer will go through Misc/NEWS periodically and add - changes; it's therefore more important to add your changes to - Misc/NEWS than to this file. - - * This is not a complete list of every single change; completeness - is the purpose of Misc/NEWS. Some changes I consider too small - or esoteric to include. If such a change is added to the text, - I'll just remove it. (This is another reason you shouldn't spend - too much time on writing your addition.) - - * If you want to draw your new text to the attention of the - maintainer, add 'XXX' to the beginning of the paragraph or - section. - - * It's OK to just add a fragmentary note about a change. For - example: "XXX Describe the transmogrify() function added to the - socket module." The maintainer will research the change and - write the necessary text. - - * You can comment out your additions if you like, but it's not - necessary (especially when a final release is some months away). - - * Credit the author of a patch or bugfix. Just the name is - sufficient; the e-mail address isn't necessary. - - * It's helpful to add the bug/patch number as a comment: - - XXX Describe the transmogrify() function added to the socket - module. - (Contributed by P.Y. Developer in :issue:`12345`.) - - This saves the maintainer the effort of going through the Mercurial log - when researching a change. - -This article explains the new features in Python 3.9, compared to 3.8. - -For full details, see the :source:`Misc/NEWS` file. - -.. note:: - - Prerelease users should be aware that this document is currently in draft - form. It will be updated substantially as Python 3.9 moves towards release, - so it's worth checking back even after reading earlier versions. - - -Summary -- Release highlights -============================= - -.. This section singles out the most important changes in Python 3.9. - Brevity is key. - - -.. PEP-sized items next. - - - -New Features -============ - - - -Other Language Changes -====================== - - - -New Modules -=========== - -* None yet. - - -Improved Modules -================ - - -socket ------- - -Added :func:`socket.send_fds()` and :func:`socket.recv_fds` to send and -receive a file descriptor from the socket. -(Contributed by Joannah Nanjekye and Victor Stinner in :issue:`28724`.) - - -Optimizations -============= - - -Build and C API Changes -======================= - - - -Deprecated -========== - - - -Removed -======= - - - -Porting to Python 3.9 -===================== - -This section lists previously described changes and other bugfixes -that may require changes to your code. - - From b134b4808cd475051d27608a46e724d6a4634d6a Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Thu, 13 Jun 2019 12:56:59 -0300 Subject: [PATCH 21/26] Update test_socket.py --- Lib/test/test_socket.py | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 160e053c4391fc..789cd5fdda9f4b 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2274,32 +2274,7 @@ def testFromFd(self): def _testFromFd(self): self.serv_conn.send(MSG) - - @requireAttrs(socket.socket, "sendmsg") - @requireAttrs(socket, "AF_UNIX") - @unittest.skipIf(sys.platform == 'darwin', 'test not working for MacOSX') - @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd', 'gnukfreebsd')), 'test not working for freebsd') - def testSendAndRecvFds(self): - fds = [] - # create two new file descriptors. - for i in range(2): - fd, path = tempfile.mkstemp() - self.addCleanup(os.unlink, path) - self.addCleanup(os.close, fd) - os.write(fd, str(i).encode()) - fds.append(fd) - f = self.cli_conn.detach() - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, fileno=f) - self.addCleanup(sock.close) - with sock: - socket.send_fds(sock, [MSG], fds) - msg, fds_list, flags, addr = socket.recv_fds(sock, len(MSG), 1024) - self.assertEqual(msg, MSG) - - @testSendAndRecvFds.client_skip - def _testSendAndRecvFds(self): - self.serv_conn.send(MSG) - + def testDup(self): # Testing dup() sock = self.cli_conn.dup() From ee950f8276ef8d518d8385b92b8162d36dda37dd Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Thu, 13 Jun 2019 12:58:33 -0300 Subject: [PATCH 22/26] Update test_socket.py --- Lib/test/test_socket.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 789cd5fdda9f4b..e90a9bcf6328e7 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6296,6 +6296,7 @@ def close_fds(fds): for index, fd in enumerate(fds2): data = os.read(fd, 100) self.assertEqual(data, str(index).encode()) + if __name__ == "__main__": test_main() From 36e157d32dd13a6a74a0751e69ecb8eae3a40189 Mon Sep 17 00:00:00 2001 From: Joannah nanjekye Date: Thu, 13 Jun 2019 13:42:05 -0300 Subject: [PATCH 23/26] fix space --- Lib/test/test_socket.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index e90a9bcf6328e7..63d71a245beae8 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2274,7 +2274,7 @@ def testFromFd(self): def _testFromFd(self): self.serv_conn.send(MSG) - + def testDup(self): # Testing dup() sock = self.cli_conn.dup() @@ -6296,7 +6296,7 @@ def close_fds(fds): for index, fd in enumerate(fds2): data = os.read(fd, 100) self.assertEqual(data, str(index).encode()) - + if __name__ == "__main__": test_main() From 0f03c4270778403aa6b2d6a9472f9b1817c3f56b Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye Date: Sat, 24 Aug 2019 16:18:12 +0000 Subject: [PATCH 24/26] Do not skip Macos in tests --- Doc/library/socket.rst | 2 +- Lib/socket.py | 7 ++++++- Lib/test/test_socket.py | 1 - .../next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 5d760fcb500250..7fa35464c39e59 100755 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1584,7 +1584,7 @@ to sockets. .. note:: - Any truncated integers at the end are ignored. + Any truncated integers at the end of the list of file descriptors. .. method:: socket.sendfile(file, offset=0, count=None) diff --git a/Lib/socket.py b/Lib/socket.py index 302555ec69f932..010a3e5dd9907d 100755 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -51,7 +51,7 @@ import _socket from _socket import * -import os, sys, io, selectors, array +import os, sys, io, selectors from enum import IntEnum, IntFlag try: @@ -466,6 +466,8 @@ def fromfd(fd, family, type, proto=0): return socket(family, type, proto, nfd) if hasattr(_socket.socket, "sendmsg"): + import array + def send_fds(sock, buffers, fds, flags=0, address=None): """ send_fds(sock, buffers, fds[, flags[, address]]) -> socket object @@ -476,6 +478,8 @@ def send_fds(sock, buffers, fds, flags=0, address=None): __all__.append("send_fds") if hasattr(_socket.socket, "recvmsg"): + import array + def recv_fds(sock, bufsize, maxfds, flags=0): """ recv_fds(sock, bufsize, maxfds[, flags]) -> (socket object, socket object) @@ -491,6 +495,7 @@ def recv_fds(sock, bufsize, maxfds, flags=0): # Append data, ignoring any truncated integers at the end. fds.frombytes(cmsg_data[: len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + return msg, list(fds), flags, addr __all__.append("recv_fds") diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 63d71a245beae8..31a05a437dcdd0 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6259,7 +6259,6 @@ def test_main(): @requireAttrs(socket, "recv_fds") @requireAttrs(socket, "AF_UNIX") class SendRecvFdsTests(unittest.TestCase): - @unittest.skipIf(sys.platform == 'darwin', 'test not working for MacOSX') def testSendAndRecvFds(self): def close_pipes(pipes): for fd1, fd2 in pipes: diff --git a/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst b/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst index 499b88010d4e65..68c469810a37bb 100755 --- a/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst +++ b/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst @@ -1,2 +1,2 @@ -The socket module now has the :meth:`socket.send_fds` and :meth:`socket.recv.fds` methods. +The socket module now has the :func:`socket.send_fds` and :func:`socket.recv.fds` methods. Contributed by Joannah Nanjekye, Shinya Okano and Victor Stinner. \ No newline at end of file From bf67bd88eb6a3e980e2874d2ac0543e6fac963dd Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye Date: Wed, 28 Aug 2019 13:07:43 +0000 Subject: [PATCH 25/26] Fix doc strings --- Doc/library/socket.rst | 3 ++- Lib/socket.py | 7 ++++--- Lib/test/test_socket.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 7fa35464c39e59..a151095dd2449a 100755 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1567,6 +1567,7 @@ to sockets. .. method:: socket.send_fds(sock, buffers, fds[, flags[, address]]) Send the list of file descriptors *fds* over an :const:`AF_UNIX` socket. + The *fds* parameter is a sequence of file descriptors. Consult :meth:`sendmsg` for the documentation of these parameters. .. availability:: Unix supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. @@ -1578,7 +1579,7 @@ to sockets. Receive up to *maxfds* file descriptors. Return ``(msg, list(fds), flags, addr)``. Consult :meth:`recvmsg` for the documentation of these parameters. - .. availability:: Unix supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. + .. availability:: Unix supporting :meth:`~socket.recvmsg` and :const:`SCM_RIGHTS` mechanism. .. versionadded:: 3.9 diff --git a/Lib/socket.py b/Lib/socket.py index 010a3e5dd9907d..ae6ca6f6b5acfa 100755 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -469,7 +469,7 @@ def fromfd(fd, family, type, proto=0): import array def send_fds(sock, buffers, fds, flags=0, address=None): - """ send_fds(sock, buffers, fds[, flags[, address]]) -> socket object + """ send_fds(sock, buffers, fds[, flags[, address]]) -> integer Send the list of file descriptors fds over an AF_UNIX socket. """ @@ -481,9 +481,10 @@ def send_fds(sock, buffers, fds, flags=0, address=None): import array def recv_fds(sock, bufsize, maxfds, flags=0): - """ recv_fds(sock, bufsize, maxfds[, flags]) -> (socket object, socket object) + """ recv_fds(sock, bufsize, maxfds[, flags]) -> (data, list of file + descriptors, msg_flags, address) - receive up to maxfds file descriptors returning the message + Receive up to maxfds file descriptors returning the message data and a list containing the descriptors. """ # Array of ints diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 31a05a437dcdd0..5216759caf9766 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6279,7 +6279,7 @@ def close_fds(fds): with sock1, sock2: socket.send_fds(sock1, [MSG], fds) # request more data and file descriptors than expected - msg, fds2, flags, addr = socket.recv_fds(sock2, len(MSG) * 2, len(fds) * 2) + msg, fds2, flags, addr = socket.recv_fds(sock2, len(MSG) * 2, len(fds) * 2) self.addCleanup(close_fds, fds2) self.assertEqual(msg, MSG) From 1ac7fbf9f3e2d744e487ac5bf2276afe3971e051 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye Date: Wed, 11 Sep 2019 15:52:02 +0000 Subject: [PATCH 26/26] Fix test --- Lib/socket.py | 3 +- Lib/test/test_socket.py | 86 ++++++++++++++++++++--------------------- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/Lib/socket.py b/Lib/socket.py index ae6ca6f6b5acfa..809a97262e2f04 100755 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -13,7 +13,7 @@ socketpair() -- create a pair of new socket objects [*] fromfd() -- create a socket object from an open file descriptor [*] send_fds() -- Send file descriptor to the socket. -recv_fds() -- Recieve file descriptor from the socket. +recv_fds() -- Recieve file descriptors from the socket. fromshare() -- create a socket object from data received from socket.share() [*] gethostname() -- return the current hostname gethostbyname() -- map a hostname to its IP number @@ -493,7 +493,6 @@ def recv_fds(sock, bufsize, maxfds, flags=0): _socket.CMSG_LEN(maxfds * fds.itemsize)) for cmsg_level, cmsg_type, cmsg_data in ancdata: if (cmsg_level == _socket.SOL_SOCKET and cmsg_type == _socket.SCM_RIGHTS): - # Append data, ignoring any truncated integers at the end. fds.frombytes(cmsg_data[: len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 5216759caf9766..058de805afafbd 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6186,11 +6186,53 @@ def test_dual_stack_client_v6(self): self.echo_server(sock) self.echo_client(("::1", port), socket.AF_INET6) +@requireAttrs(socket, "send_fds") +@requireAttrs(socket, "recv_fds") +@requireAttrs(socket, "AF_UNIX") +class SendRecvFdsTests(unittest.TestCase): + def testSendAndRecvFds(self): + def close_pipes(pipes): + for fd1, fd2 in pipes: + os.close(fd1) + os.close(fd2) + + def close_fds(fds): + for fd in fds: + os.close(fd) + + # send 10 file descriptors + pipes = [os.pipe() for _ in range(10)] + self.addCleanup(close_pipes, pipes) + fds = [rfd for rfd, wfd in pipes] + + # use a UNIX socket pair to exchange file descriptors locally + sock1, sock2 = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM) + with sock1, sock2: + socket.send_fds(sock1, [MSG], fds) + # request more data and file descriptors than expected + msg, fds2, flags, addr = socket.recv_fds(sock2, len(MSG) * 2, len(fds) * 2) + self.addCleanup(close_fds, fds2) + + self.assertEqual(msg, MSG) + self.assertEqual(len(fds2), len(fds)) + self.assertEqual(flags, 0) + # don't test addr + + # test that file descriptors are connected + for index, fds in enumerate(pipes): + rfd, wfd = fds + os.write(wfd, str(index).encode()) + + for index, rfd in enumerate(fds2): + data = os.read(rfd, 100) + self.assertEqual(data, str(index).encode()) + def test_main(): tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest, TestExceptions, BufferIOTest, BasicTCPTest2, BasicUDPTest, - UDPTimeoutTest, CreateServerTest, CreateServerFunctionalTest] + UDPTimeoutTest, CreateServerTest, CreateServerFunctionalTest, + SendRecvFdsTests] tests.extend([ NonBlockingTCPTests, @@ -6255,47 +6297,5 @@ def test_main(): support.threading_cleanup(*thread_info) -@requireAttrs(socket, "send_fds") -@requireAttrs(socket, "recv_fds") -@requireAttrs(socket, "AF_UNIX") -class SendRecvFdsTests(unittest.TestCase): - def testSendAndRecvFds(self): - def close_pipes(pipes): - for fd1, fd2 in pipes: - os.close(fd1) - os.close(fd2) - - def close_fds(fds): - for fd in fds: - os.close(fd) - - # send 10 file descriptors - pipes = [os.pipe() for _ in range(10)] - self.addCleanup(close_pipes, pipes) - fds = [fd2 for fd1, fd2 in pipes] - - # use a UNIX socket pair to exchange file descriptors locally - sock1, sock2 = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM) - with sock1, sock2: - socket.send_fds(sock1, [MSG], fds) - # request more data and file descriptors than expected - msg, fds2, flags, addr = socket.recv_fds(sock2, len(MSG) * 2, len(fds) * 2) - self.addCleanup(close_fds, fds2) - - self.assertEqual(msg, MSG) - self.assertEqual(len(fds2), len(fds)) - self.assertEqual(flags, 0) - # don't test addr - - # test that file descriptors are connected - for index, fds in enumerate(pipes): - fd1, fd2 = fds - os.write(fd1, str(index).encode()) - - for index, fd in enumerate(fds2): - data = os.read(fd, 100) - self.assertEqual(data, str(index).encode()) - - if __name__ == "__main__": test_main()