Implement raise() using pthread_kill.
This commit is contained in:
@@ -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
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user