bpo-28724: Add methods send_fds and recv_fds to the socket module (GH-12889)

The socket module now has the socket.send_fds() and socket.recv.fds() functions.
Contributed by Joannah Nanjekye, Shinya Okano (original patch)
and Victor Stinner.

Co-Authored-By: Victor Stinner <vstinner@redhat.com>
This commit is contained in:
Joannah Nanjekye 2019-09-11 18:12:21 +01:00 committed by Victor Stinner
parent 58ab13479d
commit 8d120f75fb
5 changed files with 105 additions and 1 deletions

36
Lib/socket.py Normal file → Executable file
View file

@ -12,6 +12,8 @@ Functions:
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 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
@ -542,6 +544,40 @@ def fromfd(fd, family, type, proto=0):
nfd = dup(fd)
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]]) -> integer
Send the list of file descriptors fds over an AF_UNIX socket.
"""
return sock.sendmsg(buffers, [(_socket.SOL_SOCKET,
_socket.SCM_RIGHTS, array.array("i", fds))])
__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]) -> (data, list of file
descriptors, msg_flags, address)
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(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):
fds.frombytes(cmsg_data[:
len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
return msg, list(fds), flags, addr
__all__.append("recv_fds")
if hasattr(_socket.socket, "share"):
def fromshare(info):
""" fromshare(info) -> socket object