From a99c708d0cf030513c2b2596724b270caafeb799 Mon Sep 17 00:00:00 2001 From: namilsk Date: Mon, 12 Jan 2026 21:06:06 +0300 Subject: Rewrited `SIGCHLD handler & updated nix-shell for usage with `musl` target --- init/src/signals/sigchld.rs | 62 +++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 25 deletions(-) (limited to 'init/src') diff --git a/init/src/signals/sigchld.rs b/init/src/signals/sigchld.rs index a55a00a..a02b82f 100644 --- a/init/src/signals/sigchld.rs +++ b/init/src/signals/sigchld.rs @@ -1,38 +1,50 @@ -use libc::{pid_t, - SIGCHLD, - waitpid, - WNOHANG, - sigaction, - sigemptyset, - SA_RESTART}; +use libc::{c_int, sigaction, siginfo_t, sigset_t, waitpid, SA_RESTART, SA_SIGINFO, SIGCHLD, WNOHANG}; +use std::os::raw::c_void; -use std::ffi::c_int; +// extern "C" because: +// https://doc.rust-lang.org/reference/items/external-blocks.html?spm=a2ty_o01.29997173.0.0.63e251718NCvPc#abi +// Doc comments needed... +extern "C" fn sigchld_handler( + _signal: c_int, + _info: *mut siginfo_t, + _context: *mut c_void, +) { + let saved_errno = unsafe { *libc::__errno_location() }; -fn sigchild_handler(_signal: c_int) { loop { - let mut status: c_int = 0; - let pid: pid_t = unsafe { - waitpid(-1 , &mut status, WNOHANG) - }; + let mut status: c_int = 0; + let pid = unsafe { waitpid(-1, &mut status as *mut c_int, WNOHANG) }; - if pid <= 0 { - break; + match pid { + 0 => break, + -1 => { + let errno = unsafe { *libc::__errno_location() }; + if errno == libc::ECHILD { + break; + } + } + _ => { + /* If it doesnt work, ill add the logging here */ + } } } + unsafe { *libc::__errno_location() = saved_errno }; } -pub fn setup_sigchild_handler() -> Result<(), Box> { +pub fn setup_sigchld_handler() -> Result<(), Box> { unsafe { - let mut sigact: sigaction = std::mem::zeroed(); - sigact.sa_sigaction = sigchild_handler as usize; - sigemptyset(&mut sigact.sa_mask); - sigact.sa_flags = SA_RESTART; + let mut sigact: sigaction = std::mem::zeroed(); + + sigact.sa_sigaction = sigchld_handler as usize; + sigact.sa_flags = SA_RESTART | SA_SIGINFO; + + libc::sigemptyset(&mut sigact.sa_mask as *mut sigset_t); + libc::sigaddset(&mut sigact.sa_mask as *mut sigset_t, SIGCHLD); - if sigaction(SIGCHLD, &sigact, std::ptr::null_mut()) == -1 { - Err("Sigaction check returned -1".into()) - } else { - Ok(()) + if libc::sigaction(SIGCHLD, &sigact, std::ptr::null_mut()) == -1 { + return Err("Failed to set SIGCHLD handler".into()); } } -} + Ok(()) +} -- cgit v1.2.3