diff -r 53f5e16695d0 Lib/socket.py --- a/Lib/socket.py Thu Nov 17 01:50:16 2016 -0800 +++ b/Lib/socket.py Fri Nov 18 00:03:08 2016 +0900 @@ -49,7 +49,7 @@ import _socket from _socket import * -import os, sys, io, selectors +import os, sys, io, selectors, array from enum import IntEnum, IntFlag try: @@ -451,6 +451,36 @@ get_inheritable.__doc__ = "Get the inheritable flag of the socket" set_inheritable.__doc__ = "Set the inheritable flag of the socket" + if hasattr(_socket.socket, 'sendmsg'): + def send_io(self, fds): + """Send file descriptor to the socket. + + This method works on the platform on which AF_UNIX is defined. + """ + fds_real = [] + for fd_or_file in fds: + if hasattr(fd_or_file, 'fileno'): + fd = fd_or_file.fileno() + else: + fd = fd_or_file + fds_real.append(fd) + self.sendmsg([b"\x00"], + [(_socket.SOL_SOCKET, + _socket.SCM_RIGHTS, + array.array("i", fds_real))]) + def recv_io(self, max_fds=1024): + """Receive file descriptor from the socket. + + This method works on the platform on which AF_UNIX is defined. + """ + fds = array.array("i") + msg, ancdata, flags, addr = self.recvmsg( + 1, _socket.CMSG_LEN(max_fds * 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) + return list(fds) + def fromfd(fd, family, type, proto=0): """ fromfd(fd, family, type[, proto]) -> socket object