Skip to content

Commit 8e04fdd

Browse files
committed
simplify socket handling
1 parent d253966 commit 8e04fdd

File tree

1 file changed

+16
-23
lines changed

1 file changed

+16
-23
lines changed

Lib/test/test_sys.py

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from test import support
1919
from test.support import os_helper
2020
from test.support.script_helper import assert_python_ok, assert_python_failure
21+
from test.support.socket_helper import find_unused_port
2122
from test.support import threading_helper
2223
from test.support import import_helper
2324
from 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'''
19901988
import sys
19911989
import time
19921990
import 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
19991997
sock.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

Comments
 (0)