Implement raise() using pthread_kill.

This commit is contained in:
4lDO2
2024-07-17 17:41:10 +02:00
parent 4354bc94e8
commit ac5ac928f2
7 changed files with 27 additions and 22 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
cargo fmt --package relibc --package crt0 "$@"
cargo fmt --package relibc --package crt0 --package redox-rt "$@"
+16 -8
View File
@@ -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),
}
}
+1 -1
View File
@@ -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]
+4 -7
View File
@@ -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 {
+1 -1
View File
@@ -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;
+1 -2
View File
@@ -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 {
+3 -2
View File
@@ -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 {