From 8298417dee977af9bb1c66cb8ec376084280fa2b Mon Sep 17 00:00:00 2001
From: 4lDO2 <4lDO2@protonmail.com>
Date: Mon, 1 Jul 2024 20:10:00 +0200
Subject: [PATCH] Implement sigpending on Redox.

---
 redox-rt/src/signal.rs       |  9 +++++++++
 src/header/signal/mod.rs     |  8 ++++++--
 src/platform/linux/signal.rs | 11 +++++++++--
 src/platform/pal/signal.rs   |  2 +-
 src/platform/redox/signal.rs |  6 +++---
 5 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs
index 313519cf..bd174fe6 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 3b15084c..ec6241de 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 8762af6a..c92cd2ff 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 d478ec16..a802270f 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 b495c590..dc5e816f 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(
-- 
GitLab