Implement SA_RESTART for read and write.
This commit is contained in:
@@ -26,6 +26,7 @@ pub struct SigArea {
|
||||
pub altstack_bottom: usize,
|
||||
pub disable_signals_depth: u64,
|
||||
pub pctl: usize, // TODO: find out how to correctly reference that static
|
||||
pub last_sig_was_restart: bool,
|
||||
}
|
||||
|
||||
#[repr(C, align(16))]
|
||||
|
||||
@@ -44,7 +44,6 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
|
||||
// asm counts from 0
|
||||
stack.sig_num += 1;
|
||||
|
||||
arch_pre(stack, &mut *os.arch.get());
|
||||
|
||||
let sigaction = {
|
||||
@@ -61,6 +60,7 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
}
|
||||
action
|
||||
};
|
||||
let shall_restart = sigaction.flags.contains(SigactionFlags::RESTART);
|
||||
|
||||
let handler = match sigaction.kind {
|
||||
SigactionKind::Ignore => {
|
||||
@@ -123,6 +123,8 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
|
||||
//let _ = syscall::write(1, alloc::format!("will return to {:x?}\n", stack.regs.eip).as_bytes());
|
||||
|
||||
(*os.arch.get()).last_sig_was_restart = shall_restart;
|
||||
|
||||
// And re-enable them again
|
||||
control_flags.store(control_flags.load(Ordering::Relaxed) & !SigcontrolFlags::INHIBIT_DELIVERY.bits(), Ordering::Release);
|
||||
core::sync::atomic::compiler_fence(Ordering::Acquire);
|
||||
|
||||
@@ -2,16 +2,22 @@ use syscall::error::{Result, Error, EINTR};
|
||||
|
||||
use crate::arch::manually_enter_trampoline;
|
||||
use crate::signal::tmp_disable_signals;
|
||||
use crate::Tcb;
|
||||
|
||||
#[inline]
|
||||
fn wrapper(mut f: impl FnMut() -> Result<usize>) -> Result<usize> {
|
||||
loop {
|
||||
let _guard = tmp_disable_signals();
|
||||
let rt_sigarea = unsafe { &Tcb::current().unwrap().os_specific };
|
||||
let res = f();
|
||||
|
||||
if res == Err(Error::new(EINTR)) {
|
||||
unsafe {
|
||||
manually_enter_trampoline();
|
||||
}
|
||||
if unsafe { (*rt_sigarea.arch.get()).last_sig_was_restart } {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user