Run forkserver.
(listener_fd, alive_r, preload, main_path=None, sys_path=None,
*, sys_argv=None, authkey_r=None, on_error='ignore')
| 291 | |
| 292 | |
| 293 | def main(listener_fd, alive_r, preload, main_path=None, sys_path=None, |
| 294 | *, sys_argv=None, authkey_r=None, on_error='ignore'): |
| 295 | """Run forkserver.""" |
| 296 | if authkey_r is not None: |
| 297 | try: |
| 298 | authkey = os.read(authkey_r, _AUTHKEY_LEN) |
| 299 | assert len(authkey) == _AUTHKEY_LEN, f'{len(authkey)} < {_AUTHKEY_LEN}' |
| 300 | finally: |
| 301 | os.close(authkey_r) |
| 302 | else: |
| 303 | authkey = b'' |
| 304 | |
| 305 | _handle_preload(preload, main_path, sys_path, sys_argv, on_error) |
| 306 | |
| 307 | util._close_stdin() |
| 308 | |
| 309 | sig_r, sig_w = os.pipe() |
| 310 | os.set_blocking(sig_r, False) |
| 311 | os.set_blocking(sig_w, False) |
| 312 | |
| 313 | def sigchld_handler(*_unused): |
| 314 | # Dummy signal handler, doesn't do anything |
| 315 | pass |
| 316 | |
| 317 | handlers = { |
| 318 | # unblocking SIGCHLD allows the wakeup fd to notify our event loop |
| 319 | signal.SIGCHLD: sigchld_handler, |
| 320 | # protect the process from ^C |
| 321 | signal.SIGINT: signal.SIG_IGN, |
| 322 | } |
| 323 | old_handlers = {sig: signal.signal(sig, val) |
| 324 | for (sig, val) in handlers.items()} |
| 325 | |
| 326 | # calling os.write() in the Python signal handler is racy |
| 327 | signal.set_wakeup_fd(sig_w) |
| 328 | |
| 329 | # map child pids to client fds |
| 330 | pid_to_fd = {} |
| 331 | |
| 332 | with socket.socket(socket.AF_UNIX, fileno=listener_fd) as listener, \ |
| 333 | selectors.DefaultSelector() as selector: |
| 334 | _forkserver._forkserver_address = listener.getsockname() |
| 335 | |
| 336 | selector.register(listener, selectors.EVENT_READ) |
| 337 | selector.register(alive_r, selectors.EVENT_READ) |
| 338 | selector.register(sig_r, selectors.EVENT_READ) |
| 339 | |
| 340 | while True: |
| 341 | try: |
| 342 | while True: |
| 343 | rfds = [key.fileobj for (key, events) in selector.select()] |
| 344 | if rfds: |
| 345 | break |
| 346 | |
| 347 | if alive_r in rfds: |
| 348 | # EOF because no more client processes left |
| 349 | assert os.read(alive_r, 1) == b'', "Not at EOF?" |
| 350 | raise SystemExit |
nothing calls this directly
no test coverage detected
searching dependent graphs…