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_PDEATHSIGinspawn_host_unixandsrv_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 forkill_process_group_forcefully’skill(-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 explicitterminate_child_gracefullySIGTERM in the cleanup epilogue below (after the launcher’s own SIGINT arm has already won theselect!and broken the loop), never by an independent signal race inside the loop. See the (now narrower) group-shutdown guard comments on thehost_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 usestokio::net::UnixStream. Seeipc::server::run_ipc_server(Unix arm) andcrates/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).