diff options
| author | srdusr <[email protected]> | 2025-02-10 09:35:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2025-02-10 09:35:00 +0200 |
| commit | b1609928eeea54578cd0cd18935110260cb23a11 (patch) | |
| tree | 48d84542ce460b7efc580b1a6902883e28f9ae5e | |
| parent | 1320536187c822654dbd33d45649b3e151d54815 (diff) | |
| download | srdwm-b1609928eeea54578cd0cd18935110260cb23a11.tar.gz srdwm-b1609928eeea54578cd0cd18935110260cb23a11.zip | |
Reap spawned child processes instead of leaking zombies
Every srd.spawn/Command::spawn call fires and forgets its Child handle
by design (a compositor's main loop can't block waiting on an arbitrary
launched command), but nothing else was reaping them either, so every
one that exited stayed a zombie for the rest of the session. Confirmed
live via an AGS peer session's own ps: six zombies from four different
programs, spread across half an hour of ordinary use.
Explicitly ignoring SIGCHLD is the standard fix for exactly this case --
the kernel reaps exited children itself, no waitpid loop needed.
| -rw-r--r-- | crates/srdwm/src/main.rs | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/crates/srdwm/src/main.rs b/crates/srdwm/src/main.rs index 7e25fec..bb331dc 100644 --- a/crates/srdwm/src/main.rs +++ b/crates/srdwm/src/main.rs @@ -54,6 +54,22 @@ fn install_signal_handlers() { unsafe { libc::signal(libc::SIGTERM, handle_shutdown_signal as *const () as libc::sighandler_t); libc::signal(libc::SIGINT, handle_shutdown_signal as *const () as libc::sighandler_t); + // Every `srd.spawn(...)`/`std::process::Command::spawn` call in this + // codebase (`fn_spawn` in config/general.rs, scratchpad toggles, + // screenshot commands, XWayland's own child) fires the process and + // drops the `Child` handle without ever calling `.wait()` on it -- + // by design, since a compositor's main loop has no business + // blocking on an arbitrary spawned command. Nothing else was + // reaping them either, so every one that exited stayed a zombie for + // the rest of the session: confirmed live via an AGS peer session's + // own `ps`, six zombies (four different programs, half an hour + // apart) all parented to this process. Explicitly ignoring SIGCHLD + // is the standard POSIX fix for exactly "I spawn children I never + // wait() on and don't care about their exit status" - the kernel + // reaps them itself the instant they exit, no handler/waitpid loop + // needed. Harmless to XWayland's own child processes and to + // anything else this compositor ever spawns for the same reason. + libc::signal(libc::SIGCHLD, libc::SIG_IGN); } } |