mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 08:53:29 +00:00
Enable sig_action test from gVisor test
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
7e96810e1a
commit
d366043876
@ -2,7 +2,12 @@
|
|||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
|
||||||
use super::{c_types::sigaction_t, constants::*, sig_mask::SigMask, sig_num::SigNum};
|
use super::{
|
||||||
|
c_types::sigaction_t,
|
||||||
|
constants::*,
|
||||||
|
sig_mask::{SigMask, SigSet},
|
||||||
|
sig_num::SigNum,
|
||||||
|
};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
|
||||||
@ -19,16 +24,20 @@ pub enum SigAction {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<sigaction_t> for SigAction {
|
impl From<sigaction_t> for SigAction {
|
||||||
type Error = Error;
|
fn from(input: sigaction_t) -> Self {
|
||||||
|
match input.handler_ptr {
|
||||||
fn try_from(input: sigaction_t) -> Result<Self> {
|
|
||||||
let action = match input.handler_ptr {
|
|
||||||
SIG_DFL => SigAction::Dfl,
|
SIG_DFL => SigAction::Dfl,
|
||||||
SIG_IGN => SigAction::Ign,
|
SIG_IGN => SigAction::Ign,
|
||||||
_ => {
|
_ => {
|
||||||
let flags = SigActionFlags::from_bits_truncate(input.flags);
|
let flags = SigActionFlags::from_bits_truncate(input.flags);
|
||||||
let mask = input.mask.into();
|
let mask = {
|
||||||
|
let mut sigset = SigSet::from(input.mask);
|
||||||
|
// SIGSTOP and SIGKILL cannot be masked
|
||||||
|
sigset -= SIGSTOP;
|
||||||
|
sigset -= SIGKILL;
|
||||||
|
sigset
|
||||||
|
};
|
||||||
SigAction::User {
|
SigAction::User {
|
||||||
handler_addr: input.handler_ptr,
|
handler_addr: input.handler_ptr,
|
||||||
flags,
|
flags,
|
||||||
@ -36,8 +45,7 @@ impl TryFrom<sigaction_t> for SigAction {
|
|||||||
mask,
|
mask,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
Ok(action)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +113,7 @@ impl SigActionFlags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The default action to signals
|
/// The default action to signals
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum SigDefaultAction {
|
pub enum SigDefaultAction {
|
||||||
Term, // Default action is to terminate the process.
|
Term, // Default action is to terminate the process.
|
||||||
Ign, // Default action is to ignore the signal.
|
Ign, // Default action is to ignore the signal.
|
||||||
|
@ -3,7 +3,16 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::signal::{c_types::sigaction_t, sig_action::SigAction, sig_num::SigNum},
|
process::{
|
||||||
|
posix_thread::AsPosixThread,
|
||||||
|
signal::{
|
||||||
|
c_types::sigaction_t,
|
||||||
|
constants::{SIGKILL, SIGSTOP},
|
||||||
|
sig_action::{SigAction, SigDefaultAction},
|
||||||
|
sig_mask::SigSet,
|
||||||
|
sig_num::SigNum,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_rt_sigaction(
|
pub fn sys_rt_sigaction(
|
||||||
@ -29,10 +38,18 @@ pub fn sys_rt_sigaction(
|
|||||||
let mut sig_dispositions = ctx.process.sig_dispositions().lock();
|
let mut sig_dispositions = ctx.process.sig_dispositions().lock();
|
||||||
|
|
||||||
let old_action = if sig_action_addr != 0 {
|
let old_action = if sig_action_addr != 0 {
|
||||||
|
if sig_num == SIGKILL || sig_num == SIGSTOP {
|
||||||
|
return_errno_with_message!(
|
||||||
|
Errno::EINVAL,
|
||||||
|
"cannot set a new signal action for SIGKILL and SIGSTOP"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let sig_action_c = ctx.user_space().read_val::<sigaction_t>(sig_action_addr)?;
|
let sig_action_c = ctx.user_space().read_val::<sigaction_t>(sig_action_addr)?;
|
||||||
let sig_action = SigAction::try_from(sig_action_c).unwrap();
|
let sig_action = SigAction::from(sig_action_c);
|
||||||
trace!("sig action = {:?}", sig_action);
|
trace!("sig action = {:?}", sig_action);
|
||||||
sig_dispositions.set(sig_num, sig_action)
|
discard_signals_if_ignored(ctx, sig_num, &sig_action);
|
||||||
|
sig_dispositions.set(sig_num, sig_action)?
|
||||||
} else {
|
} else {
|
||||||
sig_dispositions.get(sig_num)
|
sig_dispositions.get(sig_num)
|
||||||
};
|
};
|
||||||
@ -45,3 +62,39 @@ pub fn sys_rt_sigaction(
|
|||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Discard signals if the new action is to ignore the signal.
|
||||||
|
///
|
||||||
|
/// Ref: <https://elixir.bootlin.com/linux/v6.13/source/kernel/signal.c#L4323>
|
||||||
|
//
|
||||||
|
// POSIX 3.3.1.3:
|
||||||
|
// Setting a signal action to SIG_IGN for a signal that is
|
||||||
|
// pending shall cause the pending signal to be discarded,
|
||||||
|
// whether or not it is blocked.
|
||||||
|
//
|
||||||
|
// Setting a signal action to SIG_DFL for a signal that is
|
||||||
|
// pending and whose default action is to ignore the signal
|
||||||
|
// (for example, SIGCHLD), shall cause the pending signal to
|
||||||
|
// be discarded, whether or not it is blocked
|
||||||
|
fn discard_signals_if_ignored(ctx: &Context, signum: SigNum, sig_action: &SigAction) {
|
||||||
|
match sig_action {
|
||||||
|
SigAction::Dfl => {
|
||||||
|
let default_action = SigDefaultAction::from_signum(signum);
|
||||||
|
if default_action != SigDefaultAction::Ign {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SigAction::Ign => {}
|
||||||
|
SigAction::User { .. } => return,
|
||||||
|
}
|
||||||
|
|
||||||
|
let mask = SigSet::new_full() - signum;
|
||||||
|
|
||||||
|
for task in ctx.process.tasks().lock().as_slice() {
|
||||||
|
let Some(posix_thread) = task.as_posix_thread() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
posix_thread.dequeue_signal(&mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -42,6 +42,7 @@ TESTS ?= \
|
|||||||
sched_yield_test \
|
sched_yield_test \
|
||||||
semaphore_test \
|
semaphore_test \
|
||||||
sendfile_test \
|
sendfile_test \
|
||||||
|
sigaction_test \
|
||||||
sigaltstack_test \
|
sigaltstack_test \
|
||||||
stat_test \
|
stat_test \
|
||||||
stat_times_test \
|
stat_times_test \
|
||||||
|
Reference in New Issue
Block a user