From e6c06a7cf7ca2881fb747b463abf0516d4ed85c1 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Thu, 17 Apr 2025 15:47:14 +0200 Subject: [PATCH] Fix signals for spawned threads, and async signal waiting. --- redox-rt/src/signal.rs | 14 +++++++++++--- src/header/signal/mod.rs | 4 +++- src/ld_so/start.rs | 2 +- src/pthread/mod.rs | 13 +++++++++---- src/start.rs | 2 +- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs index 35ba4c3863..5810398232 100644 --- a/redox-rt/src/signal.rs +++ b/redox-rt/src/signal.rs @@ -579,8 +579,8 @@ const fn sig_bit(sig: u32) -> u64 { 1 << (sig - 1) } -pub fn setup_sighandler(tcb: &RtTcb) { - { +pub fn setup_sighandler(tcb: &RtTcb, first_thread: bool) { + if first_thread { let _guard = SIGACTIONS_LOCK.lock(); for (sig_idx, action) in PROC_CONTROL_STRUCT.actions.iter().enumerate() { let sig = sig_idx + 1; @@ -739,17 +739,25 @@ pub fn await_signal_async(inner_allowset: u64) -> Result { }, &mut TimeSpec::default(), ); - set_allowset_raw(&control.word, inner_allowset, old_allowset); if res == Err(Error::new(EINTR)) { unsafe { manually_enter_trampoline(); } } + // POSIX says it shall restore the mask to what it was prior to the call, which is interpreted + // as allowing any changes to sigprocmask inside the signal handler, to be discarded. + set_allowset_raw(&control.word, inner_allowset, old_allowset); res?; unreachable!() } +/*#[no_mangle] +pub extern "C" fn __redox_rt_debug_sigctl() { + let tcb = &RtTcb::current().control; + let _ = syscall::write(1, alloc::format!("SIGCTL: {tcb:#x?}\n").as_bytes()); +}*/ + // TODO: deadline-based API pub fn await_signal_sync(inner_allowset: u64, timeout: Option<&TimeSpec>) -> Result { let _guard = tmp_disable_signals(); diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs index 9f00dbc1ae..925a584475 100644 --- a/src/header/signal/mod.rs +++ b/src/header/signal/mod.rs @@ -309,7 +309,9 @@ pub unsafe extern "C" fn sigpause(sig: c_int) -> c_int { let mut pset = mem::MaybeUninit::::uninit(); sigprocmask(0, ptr::null_mut(), pset.as_mut_ptr()); let mut set = pset.assume_init(); - sigdelset(&mut set, sig); + if sigdelset(&mut set, sig) == -1 { + return -1; + } sigsuspend(&set) } diff --git a/src/ld_so/start.rs b/src/ld_so/start.rs index 390a77c09a..26e1a0f3a3 100644 --- a/src/ld_so/start.rs +++ b/src/ld_so/start.rs @@ -168,7 +168,7 @@ pub unsafe extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: us .expect_notls("no proc fd present"); redox_rt::initialize(redox_rt::proc::FdGuard::new(proc_fd)); - redox_rt::signal::setup_sighandler(&tcb.os_specific); + redox_rt::signal::setup_sighandler(&tcb.os_specific, true); } } diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs index b41a19d5cc..bdf70af6ba 100644 --- a/src/pthread/mod.rs +++ b/src/pthread/mod.rs @@ -213,10 +213,15 @@ unsafe extern "C" fn new_thread_shim( let tid = (*(&*mutex1).lock()).assume_init(); if let Some(tcb) = tcb.as_mut() { - tcb.activate( - #[cfg(target_os = "redox")] - redox_rt::proc::FdGuard::new(tid.thread_fd), - ); + #[cfg(not(target_os = "redox"))] + { + tcb.activate(); + } + #[cfg(target_os = "redox")] + { + tcb.activate(redox_rt::proc::FdGuard::new(tid.thread_fd)); + redox_rt::signal::setup_sighandler(&tcb.os_specific, false); + } } let procmask = (&*mutex2).as_ptr().read(); diff --git a/src/start.rs b/src/start.rs index faca8b65ec..279dcbe317 100644 --- a/src/start.rs +++ b/src/start.rs @@ -171,7 +171,7 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! { tcb.linker_ptr = Box::into_raw(Box::new(Mutex::new(linker))); } #[cfg(target_os = "redox")] - redox_rt::signal::setup_sighandler(&tcb.os_specific); + redox_rt::signal::setup_sighandler(&tcb.os_specific, true); } // Set up argc and argv