diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs index 313519cff9beb147133bb601c20737317a873029..bd174fe6e879ed0aed3541abbd5a968f58571020 100644 --- a/redox-rt/src/signal.rs +++ b/redox-rt/src/signal.rs @@ -497,3 +497,12 @@ pub unsafe fn sigaltstack(new: Option<&Sigaltstack>, old_out: Option<&mut Sigalt } pub const MIN_SIGALTSTACK_SIZE: usize = 8192; + +pub fn currently_pending() -> u64 { + let control = &unsafe { Tcb::current().unwrap() }.os_specific.control; + let w0 = control.word[0].load(Ordering::Relaxed); + let w1 = control.word[0].load(Ordering::Relaxed); + let pending_blocked_lo = w0 & !(w0 >> 32); + let pending_unblocked_hi = w1 & !(w0 >> 32); + pending_blocked_lo | (pending_unblocked_hi << 32) +} diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs index 3b15084c2301bb13ce55c8b0aec7d3d8dab31448..ec6241de54c6b98637db89413cd57c0bd0603348 100644 --- a/src/header/signal/mod.rs +++ b/src/header/signal/mod.rs @@ -7,11 +7,13 @@ use cbitset::BitSet; use crate::{ header::{errno, time::timespec}, platform::{self, types::*, Pal, PalSignal, Sys}, - pthread::{self, ResultExt}, + pthread::{self, Errno, ResultExt}, }; pub use self::sys::*; +use super::errno::EFAULT; + #[cfg(target_os = "linux")] #[path = "linux.rs"] pub mod sys; @@ -241,7 +243,9 @@ pub unsafe extern "C" fn sigpause(sig: c_int) -> c_int { #[no_mangle] pub unsafe extern "C" fn sigpending(set: *mut sigset_t) -> c_int { - Sys::sigpending(set) + (|| Sys::sigpending(set.as_mut().ok_or(Errno(EFAULT))?))() + .map(|()| 0) + .or_minus_one_errno() } const BELOW_SIGRTMIN_MASK: sigset_t = (1 << SIGRTMIN) - 1; diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs index 8762af6a6decac7bab45523bfe82319c704ffc6b..c92cd2ff01344f2db227e17b173203a1d743d971 100644 --- a/src/platform/linux/signal.rs +++ b/src/platform/linux/signal.rs @@ -74,8 +74,15 @@ impl PalSignal for Sys { .map(|_| ()) } - unsafe fn sigpending(set: *mut sigset_t) -> c_int { - e(syscall!(RT_SIGPENDING, set, NSIG / 8)) as c_int + fn sigpending(set: &mut sigset_t) -> Result<(), Errno> { + e_raw(unsafe { + syscall!( + RT_SIGPENDING, + set as *mut sigset_t as usize, + mem::size_of::<sigset_t>() + ) + }) + .map(|_| ()) } fn sigprocmask( diff --git a/src/platform/pal/signal.rs b/src/platform/pal/signal.rs index d478ec16c82d0fd5359375d441e15956d91c9013..a802270fa0f6a223c6e05f439eec5116b08fc74f 100644 --- a/src/platform/pal/signal.rs +++ b/src/platform/pal/signal.rs @@ -27,7 +27,7 @@ pub trait PalSignal: Pal { unsafe fn sigaltstack(ss: Option<&stack_t>, old_ss: Option<&mut stack_t>) -> Result<(), Errno>; - unsafe fn sigpending(set: *mut sigset_t) -> c_int; + fn sigpending(set: &mut sigset_t) -> Result<(), Errno>; fn sigprocmask( how: c_int, diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index b495c590fd9c08bd4d82fbbf82281636fe361b9a..dc5e816ff2fa5f349ce55b40688f5139d6825315 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -223,9 +223,9 @@ impl PalSignal for Sys { Ok(()) } - unsafe fn sigpending(set: *mut sigset_t) -> c_int { - ERRNO.set(ENOSYS); - -1 + fn sigpending(set: &mut sigset_t) -> Result<(), Errno> { + *set = redox_rt::signal::currently_pending(); + Ok(()) } fn sigprocmask(