Receive an array of fds over an AF_UNIX socket.
(sock, size)
| 148 | raise RuntimeError('did not receive acknowledgement of fd') |
| 149 | |
| 150 | def recvfds(sock, size): |
| 151 | '''Receive an array of fds over an AF_UNIX socket.''' |
| 152 | a = array.array('i') |
| 153 | bytes_size = a.itemsize * size |
| 154 | msg, ancdata, flags, addr = sock.recvmsg(1, socket.CMSG_SPACE(bytes_size)) |
| 155 | if not msg and not ancdata: |
| 156 | raise EOFError |
| 157 | try: |
| 158 | # We send/recv an Ack byte after the fds to work around an old |
| 159 | # macOS bug; it isn't clear if this is still required but it |
| 160 | # makes unit testing fd sending easier. |
| 161 | # See: https://github.com/python/cpython/issues/58874 |
| 162 | sock.send(b'A') # Acknowledge |
| 163 | if len(ancdata) != 1: |
| 164 | raise RuntimeError('received %d items of ancdata' % |
| 165 | len(ancdata)) |
| 166 | cmsg_level, cmsg_type, cmsg_data = ancdata[0] |
| 167 | if (cmsg_level == socket.SOL_SOCKET and |
| 168 | cmsg_type == socket.SCM_RIGHTS): |
| 169 | if len(cmsg_data) % a.itemsize != 0: |
| 170 | raise ValueError |
| 171 | a.frombytes(cmsg_data) |
| 172 | if len(a) % 256 != msg[0]: |
| 173 | raise AssertionError( |
| 174 | "Len is {0:n} but msg[0] is {1!r}".format( |
| 175 | len(a), msg[0])) |
| 176 | return list(a) |
| 177 | except (ValueError, IndexError): |
| 178 | pass |
| 179 | raise RuntimeError('Invalid data received') |
| 180 | |
| 181 | def send_handle(conn, handle, destination_pid): |
| 182 | '''Send a handle over a local connection.''' |
no test coverage detected
searching dependent graphs…