srdusr
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-02-10 09:35:00 +0200
committersrdusr <[email protected]>2025-02-10 09:35:00 +0200
commitb1609928eeea54578cd0cd18935110260cb23a11 (patch)
tree48d84542ce460b7efc580b1a6902883e28f9ae5e
parent1320536187c822654dbd33d45649b3e151d54815 (diff)
downloadsrdwm-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.rs16
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);
}
}