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 {