Skip to main content

run_unix

Function run_unix 

Source
pub(crate) async fn run_unix(
    launcher_exe_dir: &Path,
    real_exe: &Path,
    args: &[String],
    startup_sink_opt: Option<StartupEventSink>,
)
Expand description

Unix (macOS/Linux) main flow: resolve paths → bind launcher IPC socket (single-instance signal) → set up reducer / event log / saga coordinator / IPC server → spawn srv → spawn host with srv endpoints AND the launcher socket path in env → supervised wait → cleanup.

As of A1 (SPEC_LAUNCHER_LINUX_PACKAGED_AND_SPLASH_2026_06_05.md §4) the launcher’s window/pool/instance reducer + durable saga coordinator are now live on Linux. The 17 host-side report_* IPC calls reach the reducer; the saga log persists at <data-dir>/db/launcher-sagas.db; second-instance launches are detected via socket-bind contention.

Differs from run_windows only where the OS forces it:

  • No Job Object — A0 (PR_SET_PDEATHSIG in spawn_host_unix and srv_spawner) gives the equivalent kernel-side reap when the launcher dies abnormally.
  • As of SPEC_LAUNCHER_TEARDOWN_BACKSTOP_2026_07_11 unix parity, host and srv are each spawned into their OWN process group (.process_group(0)) rather than inheriting the launcher’s — the prerequisite for kill_process_group_forcefully’s kill(-pgid, SIGKILL) to be scoped to exactly what THIS launcher spawned, never the launcher’s own group. Side effect (reagent P1, PR #2200): a terminal Ctrl+C no longer reaches host/srv directly — only the launcher (still in the terminal’s foreground group) receives that SIGINT. Host/srv now die exclusively via the launcher’s own explicit terminate_child_gracefully SIGTERM in the cleanup epilogue below (after the launcher’s own SIGINT arm has already won the select! and broken the loop), never by an independent signal race inside the loop. See the (now narrower) group-shutdown guard comments on the host_child.wait() / srv_child.wait() arms for what scenario they still cover. kill <launcher-pid> is unaffected — the launcher’s own SIGINT/SIGTERM handlers still catch it and drive the same cleanup.
  • Unix-domain-socket IPC (A1) instead of named pipes; protocol on the wire is identical (newline-delimited JSON Command/Event). The launcher-side server uses tokio::net::UnixListener; the host-side client uses tokio::net::UnixStream. See ipc::server::run_ipc_server (Unix arm) and crates/cef/src/launcher_ipc/mod.rs::connect_to_launcher (Unix arm).
  • srv-side IPC is still skipped on Unix (srv is launched with an empty srv_pipe_path); follow-up PR will bring srv’s Unix socket online too.
  • Cleanup is SIGTERM-then-SIGKILL (we own the reap) rather than KILL_ON_JOB_CLOSE.

srv’s stdin write-end is held for the launcher’s lifetime — its EOF is srv’s parent-death backstop if the launcher is SIGKILLed (the one case our signal handlers can’t cover).