From ac5ac928f27d6a3a104b723d7d24c2a4fea30ceb Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Wed, 17 Jul 2024 17:41:10 +0200 Subject: [PATCH] Implement raise() using pthread_kill. --- fmt.sh | 2 +- redox-rt/src/sys.rs | 24 ++++++++++++++++-------- src/header/signal/mod.rs | 2 +- src/platform/linux/signal.rs | 11 ++++------- src/platform/pal/signal.rs | 2 +- src/platform/redox/mod.rs | 3 +-- src/platform/redox/signal.rs | 5 +++-- 7 files changed, 27 insertions(+), 22 deletions(-) diff --git a/fmt.sh b/fmt.sh index be8636e2..8caff707 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 77750a6a..99b877a9 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 01cd57d7..4c2db6b9 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 c92cd2ff..8055904c 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 a802270f..cd9151a5 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 7e2e86b0..05378c34 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 ce156d1d..e359c540 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 { -- GitLab