Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
fix: resolve Xwayland startup failure by implementing proper SIGCHLD signal handling
src/server/process.rs | 3 ---
src/server/server.rs | 11 +++++++++++
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/server/process.rs b/src/server/process.rs
index 244fb62..97b7a75 100644
--- a/src/server/process.rs
+++ b/src/server/process.rs
@@ -9,11 +9,8 @@ static ORIGINAL_RLIMIT: Mutex<Option<libc::rlimit>> = Mutex::new(None);
pub fn setup() {
// Ignore SIGPIPE so we don't get killed when writing to a socket that
// has had its read end closed by another process.
- // Also ignore SIGCHLD to automatically reap terminated child processes
- // and prevent them from becoming zombies.
unsafe {
libc::signal(libc::SIGPIPE, libc::SIG_IGN);
- libc::signal(libc::SIGCHLD, libc::SIG_IGN);
}
// Most unix systems have a default limit of 1024 file descriptors.
diff --git a/src/server/server.rs b/src/server/server.rs
index 4df2c82..036381a 100644
--- a/src/server/server.rs
+++ b/src/server/server.rs
@@ -220,6 +220,7 @@ pub struct Server {
pub wl_server: *mut ffi::wl_display,
pub sigint_source: *mut ffi::wl_event_source,
pub sigterm_source: *mut ffi::wl_event_source,
+ pub sigchld_source: *mut ffi::wl_event_source,
// pub fixes: *mut ffi::wlr_fixes,
pub backend: *mut ffi::wlr_backend,
pub session: *mut ffi::wlr_session,
@@ -290,6 +291,12 @@ unsafe extern "C" fn terminate(_signum: std::os::raw::c_int, data: *mut std::ffi
0
}
+unsafe extern "C" fn handle_sigchld(_signum: std::os::raw::c_int, _data: *mut std::ffi::c_void) -> std::os::raw::c_int {
+ let mut status = 0;
+ while libc::waitpid(-1, &mut status, libc::WNOHANG) > 0 {}
+ 0
+}
+
unsafe extern "C" fn handle_renderer_lost(listener: *mut ffi::wl_listener, _data: *mut std::ffi::c_void) {
let _server = container_of!(listener, Server, renderer_lost);
log::info!("received GPU reset event");
@@ -464,6 +471,7 @@ impl Server {
self.sigint_source = ffi::wl_event_loop_add_signal(loop_, libc::SIGINT, Some(terminate), wl_server as *mut _);
self.sigterm_source = ffi::wl_event_loop_add_signal(loop_, libc::SIGTERM, Some(terminate), wl_server as *mut _);
+ self.sigchld_source = ffi::wl_event_loop_add_signal(loop_, libc::SIGCHLD, Some(handle_sigchld), wl_server as *mut _);
let mut session: *mut ffi::wlr_session = ptr::null_mut();
let backend = ffi::wlr_backend_autocreate(loop_, &mut session);
@@ -776,6 +784,9 @@ impl Server {
log::info!("[deinit] removing server listeners");
ffi::wl_event_source_remove(self.sigint_source);
ffi::wl_event_source_remove(self.sigterm_source);
+ if !self.sigchld_source.is_null() {
+ ffi::wl_event_source_remove(self.sigchld_source);
+ }
wl_listener_remove(&mut self.renderer_lost);
wl_listener_remove(&mut self.new_xdg_toplevel);