@@ -6436,11 +6436,53 @@ def test_dual_stack_client_v6(self):
64366436self.echo_server(sock)
64376437self.echo_client(("::1", port), socket.AF_INET6)
643864386439+@requireAttrs(socket, "send_fds")
6440+@requireAttrs(socket, "recv_fds")
6441+@requireAttrs(socket, "AF_UNIX")
6442+classSendRecvFdsTests(unittest.TestCase):
6443+deftestSendAndRecvFds(self):
6444+defclose_pipes(pipes):
6445+forfd1, fd2inpipes:
6446+os.close(fd1)
6447+os.close(fd2)
6448+6449+defclose_fds(fds):
6450+forfdinfds:
6451+os.close(fd)
6452+6453+# send 10 file descriptors
6454+pipes= [os.pipe() for_inrange(10)]
6455+self.addCleanup(close_pipes, pipes)
6456+fds= [rfdforrfd, wfdinpipes]
6457+6458+# use a UNIX socket pair to exchange file descriptors locally
6459+sock1, sock2=socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
6460+withsock1, sock2:
6461+socket.send_fds(sock1, [MSG], fds)
6462+# request more data and file descriptors than expected
6463+msg, fds2, flags, addr=socket.recv_fds(sock2, len(MSG) *2, len(fds) *2)
6464+self.addCleanup(close_fds, fds2)
6465+6466+self.assertEqual(msg, MSG)
6467+self.assertEqual(len(fds2), len(fds))
6468+self.assertEqual(flags, 0)
6469+# don't test addr
6470+6471+# test that file descriptors are connected
6472+forindex, fdsinenumerate(pipes):
6473+rfd, wfd=fds
6474+os.write(wfd, str(index).encode())
6475+6476+forindex, rfdinenumerate(fds2):
6477+data=os.read(rfd, 100)
6478+self.assertEqual(data, str(index).encode())
6479+6439648064406481deftest_main():
64416482tests= [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest,
64426483TestExceptions, BufferIOTest, BasicTCPTest2, BasicUDPTest,
6443-UDPTimeoutTest, CreateServerTest, CreateServerFunctionalTest]
6484+UDPTimeoutTest, CreateServerTest, CreateServerFunctionalTest,
6485+SendRecvFdsTests]
6444648664456487tests.extend([
64466488NonBlockingTCPTests,
@@ -6513,5 +6555,6 @@ def test_main():
65136555support.run_unittest(*tests)
65146556support.threading_cleanup(*thread_info)
651565576558+65166559if__name__=="__main__":
65176560test_main()