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(