diff --git a/fmt.sh b/fmt.sh
index be8636e2ab16a4bc43a86d252a7bd77193b6ad4a..8caff707aef2d9cb0945f62c396392e7fb499047 100755
--- a/fmt.sh
+++ b/fmt.sh
@@ -1,3 +1,3 @@
 #!/usr/bin/env bash
 
-cargo fmt --package relibc --package crt0 "$@"
+cargo fmt --package relibc --package crt0 --package redox-rt "$@"
diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs
index 77750a6a2ad23eb51d967d68d5c71940096ef67c..99b877a901207b2517f5664452297633b85725bd 100644
--- a/redox-rt/src/sys.rs
+++ b/redox-rt/src/sys.rs
@@ -3,10 +3,10 @@ use syscall::{
     TimeSpec,
 };
 
-use crate::{arch::manually_enter_trampoline, signal::tmp_disable_signals, Tcb};
+use crate::{arch::manually_enter_trampoline, proc::FdGuard, signal::tmp_disable_signals, Tcb};
 
 #[inline]
-fn wrapper<T>(mut f: impl FnMut() -> Result<T>) -> Result<T> {
+fn wrapper<T>(restart: bool, mut f: impl FnMut() -> Result<T>) -> Result<T> {
     loop {
         let _guard = tmp_disable_signals();
         let rt_sigarea = unsafe { &Tcb::current().unwrap().os_specific };
@@ -14,6 +14,7 @@ fn wrapper<T>(mut f: impl FnMut() -> Result<T>) -> Result<T> {
 
         if let Err(err) = res
             && err == Error::new(EINTR)
+            && restart
         {
             unsafe {
                 manually_enter_trampoline();
@@ -30,29 +31,29 @@ fn wrapper<T>(mut f: impl FnMut() -> Result<T>) -> Result<T> {
 // TODO: uninitialized memory?
 #[inline]
 pub fn posix_read(fd: usize, buf: &mut [u8]) -> Result<usize> {
-    wrapper(|| syscall::read(fd, buf))
+    wrapper(true, || syscall::read(fd, buf))
 }
 #[inline]
 pub fn posix_write(fd: usize, buf: &[u8]) -> Result<usize> {
-    wrapper(|| syscall::write(fd, buf))
+    wrapper(true, || syscall::write(fd, buf))
 }
 #[inline]
 pub fn posix_kill(pid: usize, sig: usize) -> Result<()> {
-    match wrapper(|| syscall::kill(pid, sig)) {
+    match wrapper(false, || syscall::kill(pid, sig)) {
         Ok(_) | Err(Error { errno: EINTR }) => Ok(()),
         Err(error) => Err(error),
     }
 }
 #[inline]
 pub fn posix_killpg(pgrp: usize, sig: usize) -> Result<()> {
-    match wrapper(|| syscall::kill(usize::wrapping_neg(pgrp), sig)) {
+    match wrapper(false, || syscall::kill(usize::wrapping_neg(pgrp), sig)) {
         Ok(_) | Err(Error { errno: EINTR }) => Ok(()),
         Err(error) => Err(error),
     }
 }
 #[inline]
 pub unsafe fn sys_futex_wait(addr: *mut u32, val: u32, deadline: Option<&TimeSpec>) -> Result<()> {
-    wrapper(|| {
+    wrapper(true, || {
         syscall::syscall5(
             syscall::SYS_FUTEX,
             addr as usize,
@@ -77,7 +78,7 @@ pub unsafe fn sys_futex_wake(addr: *mut u32, num: u32) -> Result<u32> {
     .map(|awoken| awoken as u32)
 }
 pub fn sys_waitpid(pid: usize, status: &mut usize, flags: usize) -> Result<usize> {
-    wrapper(|| {
+    wrapper(true, || {
         syscall::waitpid(
             pid,
             status,
@@ -85,3 +86,10 @@ pub fn sys_waitpid(pid: usize, status: &mut usize, flags: usize) -> Result<usize
         )
     })
 }
+pub fn posix_kill_thread(thread_fd: usize, signal: u32) -> Result<()> {
+    let killfd = FdGuard::new(syscall::dup(thread_fd, b"signal")?);
+    match wrapper(false, || syscall::write(*killfd, &signal.to_ne_bytes())) {
+        Ok(_) | Err(Error { errno: EINTR }) => Ok(()),
+        Err(error) => Err(error),
+    }
+}
diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs
index 01cd57d7ebb46e4b3b48f8ac4741905ebf3f54d9..4c2db6b90bdc3c90f5dd7024908e66b82e2eed27 100644
--- a/src/header/signal/mod.rs
+++ b/src/header/signal/mod.rs
@@ -104,7 +104,7 @@ pub unsafe extern "C" fn pthread_sigmask(
 
 #[no_mangle]
 pub extern "C" fn raise(sig: c_int) -> c_int {
-    Sys::raise(sig)
+    Sys::raise(sig).map(|()| 0).or_minus_one_errno()
 }
 
 #[no_mangle]
diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs
index c92cd2ff01344f2db227e17b173203a1d743d971..8055904c9315bfd803fda35e57d5380892f998b2 100644
--- a/src/platform/linux/signal.rs
+++ b/src/platform/linux/signal.rs
@@ -26,13 +26,10 @@ impl PalSignal for Sys {
         e(unsafe { syscall!(KILL, -(pgrp as isize) as pid_t, sig) }) as c_int
     }
 
-    fn raise(sig: c_int) -> c_int {
-        let tid = e(unsafe { syscall!(GETTID) }) as pid_t;
-        if tid == !0 {
-            -1
-        } else {
-            e(unsafe { syscall!(TKILL, tid, sig) }) as c_int
-        }
+    fn raise(sig: c_int) -> Result<(), Errno> {
+        let tid = e_raw(unsafe { syscall!(GETTID) })? as pid_t;
+        e_raw(unsafe { syscall!(TKILL, tid, sig) })?;
+        Ok(())
     }
 
     unsafe fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
diff --git a/src/platform/pal/signal.rs b/src/platform/pal/signal.rs
index a802270fa0f6a223c6e05f439eec5116b08fc74f..cd9151a50575e3e7efe69b96ab686e05ed2ee163 100644
--- a/src/platform/pal/signal.rs
+++ b/src/platform/pal/signal.rs
@@ -15,7 +15,7 @@ pub trait PalSignal: Pal {
 
     fn killpg(pgrp: pid_t, sig: c_int) -> c_int;
 
-    fn raise(sig: c_int) -> c_int;
+    fn raise(sig: c_int) -> Result<(), Errno>;
 
     unsafe fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int;
 
diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs
index 7e2e86b00bcd621b91afe019c10490e1c4f2ab35..05378c347c653f03e801a63de1f9589bf38e01a9 100644
--- a/src/platform/redox/mod.rs
+++ b/src/platform/redox/mod.rs
@@ -802,8 +802,7 @@ impl Pal for Sys {
         os_tid: crate::pthread::OsTid,
         signal: usize,
     ) -> Result<(), crate::pthread::Errno> {
-        let killfd = FdGuard::new(syscall::dup(os_tid.thread_fd, b"signal")?);
-        syscall::write(*killfd, &(signal as u32).to_ne_bytes())?;
+        redox_rt::sys::posix_kill_thread(os_tid.thread_fd, signal as u32)?;
         Ok(())
     }
     fn current_os_tid() -> crate::pthread::OsTid {
diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs
index ce156d1dea25cb6556b0a201297ce17d3c5ded88..e359c54064a38056c75a05488584e5ee351f2cd3 100644
--- a/src/platform/redox/signal.rs
+++ b/src/platform/redox/signal.rs
@@ -60,8 +60,9 @@ impl PalSignal for Sys {
         e(redox_rt::sys::posix_killpg(pgrp as usize, sig as usize).map(|()| 0)) as c_int
     }
 
-    fn raise(sig: c_int) -> c_int {
-        Self::kill(Self::getpid(), sig)
+    fn raise(sig: c_int) -> Result<(), Errno> {
+        // TODO: Bypass kernel?
+        unsafe { Self::rlct_kill(Self::current_os_tid(), sig as _) }
     }
 
     unsafe fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {