1818from test import support
1919from test .support import os_helper
2020from test .support .script_helper import assert_python_ok , assert_python_failure
21+ from test .support .socket_helper import find_unused_port
2122from test .support import threading_helper
2223from test .support import import_helper
2324from test .support import force_not_colorized
@@ -1980,20 +1981,17 @@ def _run_remote_exec_test(self, script_code, python_args=None, env=None, prologu
19801981 target = os_helper .TESTFN + '_target.py'
19811982 self .addCleanup (os_helper .unlink , target )
19821983
1983- # Find an available port for the socket
1984- with socket .socket (socket .AF_INET , socket .SOCK_STREAM ) as s :
1985- s .bind (('localhost' , 0 ))
1986- port = s .getsockname ()[1 ]
1984+ parent_sock , child_sock = socket .socketpair ()
19871985
19881986 with open (target , 'w' ) as f :
19891987 f .write (f'''
19901988import sys
19911989import time
19921990import socket
1991+ import os
19931992
1994- # Connect to the test process
1995- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1996- sock.connect(('localhost', { port } ))
1993+ # Get the socket from the passed file descriptor
1994+ sock = socket.socket(fileno={ child_sock .fileno ()} )
19971995
19981996# Signal that the process is ready
19991997sock.sendall(b"ready")
@@ -2019,32 +2017,28 @@ def _run_remote_exec_test(self, script_code, python_args=None, env=None, prologu
20192017 cmd .extend (python_args )
20202018 cmd .append (target )
20212019
2022- # Create a socket server to communicate with the target process
2023- server_socket = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
2024- server_socket .bind (('localhost' , port ))
2025- server_socket .settimeout (10.0 ) # Set a timeout to prevent hanging
2026- server_socket .listen (1 )
2027-
20282020 with subprocess .Popen (cmd ,
20292021 stdout = subprocess .PIPE ,
20302022 stderr = subprocess .PIPE ,
2031- env = env ) as proc :
2023+ env = env ,
2024+ pass_fds = [child_sock .fileno ()],
2025+ ) as proc :
20322026 try :
2033- # Accept connection from target process
2034- client_socket , _ = server_socket . accept ()
2027+ # Close the child socket in the parent process as it's now owned by the child
2028+ child_sock . close ()
20352029
2036- # Wait for process to be ready
2037- response = client_socket .recv (1024 )
2030+ # Wait for process to be ready
2031+ response = parent_sock .recv (1024 )
20382032 self .assertEqual (response , b"ready" )
20392033
20402034 # Try remote exec on the target process
20412035 sys .remote_exec (proc .pid , script )
20422036
20432037 # Signal script to continue
2044- client_socket .sendall (b"continue" )
2038+ parent_sock .sendall (b"continue" )
20452039
20462040 # Wait for execution confirmation
2047- response = client_socket .recv (1024 )
2041+ response = parent_sock .recv (1024 )
20482042 self .assertEqual (response , b"executed" )
20492043
20502044 # Return output for test verification
@@ -2053,9 +2047,8 @@ def _run_remote_exec_test(self, script_code, python_args=None, env=None, prologu
20532047 except PermissionError :
20542048 self .skipTest ("Insufficient permissions to execute code in remote process" )
20552049 finally :
2056- if 'client_socket' in locals ():
2057- client_socket .close ()
2058- server_socket .close ()
2050+ # Wait for execution confirmation
2051+ parent_sock .close ()
20592052 proc .kill ()
20602053 proc .terminate ()
20612054 proc .wait (timeout = SHORT_TIMEOUT )
0 commit comments