Skip to content

Commit 5ad98ca

Browse files
committed
Map Python pipe fds in child process
1 parent 77f930d commit 5ad98ca

1 file changed

Lines changed: 14 additions & 20 deletions

File tree

python/modcdp/launcher/LocalBrowserLauncher.py

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
import errno
43
import glob
54
import json
65
import os
@@ -87,8 +86,8 @@ def launch(self, options: BrowserLaunchOptions | None = None) -> LaunchedBrowser
8786
child_read, parent_write = os.pipe()
8887
parent_read = _move_fd_if_needed(parent_read, {3, 4})
8988
parent_write = _move_fd_if_needed(parent_write, {3, 4})
90-
child_read = _move_fd_to(child_read, 3)
91-
child_write = _move_fd_to(child_write, 4)
89+
child_read = _move_fd_if_needed(child_read, {3, 4})
90+
child_write = _move_fd_if_needed(child_write, {3, 4})
9291
process = _spawn_chrome_with_pipe_fds(executable_path, args, child_read, child_write)
9392
os.close(child_read)
9493
os.close(child_write)
@@ -220,33 +219,28 @@ def _move_fd_if_needed(fd: int, reserved: set[int]) -> int:
220219
if fd not in reserved:
221220
return fd
222221
moved = os.dup(fd)
222+
while moved in reserved:
223+
next_fd = os.dup(fd)
224+
os.close(moved)
225+
moved = next_fd
223226
os.close(fd)
224227
return moved
225228

226229

227-
def _move_fd_to(fd: int, target: int) -> int:
228-
if fd == target:
229-
return fd
230-
deadline = time.monotonic() + 1
231-
while True:
232-
try:
233-
os.dup2(fd, target)
234-
break
235-
except OSError as error:
236-
if error.errno != errno.EBUSY or time.monotonic() >= deadline:
237-
raise
238-
time.sleep(0.001)
239-
os.close(fd)
240-
return target
241-
242-
243230
def _spawn_chrome_with_pipe_fds(executable_path: str, args: list[str], child_read: int, child_write: int) -> _ChromeProcess:
231+
def map_pipe_fds() -> None:
232+
os.dup2(child_read, 3)
233+
os.dup2(child_write, 4)
234+
os.close(child_read)
235+
os.close(child_write)
236+
244237
return subprocess.Popen(
245238
[executable_path, *args],
246239
stdin=subprocess.DEVNULL,
247240
stdout=subprocess.DEVNULL,
248241
stderr=subprocess.DEVNULL,
249-
pass_fds=(child_read, child_write),
242+
close_fds=sys.platform.startswith("win"),
243+
preexec_fn=None if sys.platform.startswith("win") else map_pipe_fds,
250244
start_new_session=not sys.platform.startswith("win"),
251245
)
252246

0 commit comments

Comments
 (0)