mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-23 01:13:23 +00:00
Support flag SA_RESETHAND
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
0e8c5e7f5f
commit
6414111cc5
@ -60,7 +60,8 @@ pub fn handle_pending_signal(
|
||||
let sig_num = signal.num();
|
||||
trace!("sig_num = {:?}, sig_name = {}", sig_num, sig_num.sig_name());
|
||||
let current = posix_thread.process();
|
||||
let sig_action = current.sig_dispositions().lock().get(sig_num);
|
||||
let mut sig_dispositions = current.sig_dispositions().lock();
|
||||
let sig_action = sig_dispositions.get(sig_num);
|
||||
trace!("sig action: {:x?}", sig_action);
|
||||
match sig_action {
|
||||
SigAction::Ign => {
|
||||
@ -71,7 +72,18 @@ pub fn handle_pending_signal(
|
||||
flags,
|
||||
restorer_addr,
|
||||
mask,
|
||||
} => handle_user_signal(
|
||||
} => {
|
||||
if flags.contains(SigActionFlags::SA_RESETHAND) {
|
||||
// In Linux, SA_RESETHAND corresponds to SA_ONESHOT,
|
||||
// which means the user handler will be executed only once and then reset to the default.
|
||||
// Refer to https://elixir.bootlin.com/linux/v6.0.9/source/kernel/signal.c#L2761.
|
||||
sig_dispositions.set_default(sig_num);
|
||||
}
|
||||
|
||||
drop(sig_dispositions);
|
||||
|
||||
handle_user_signal(
|
||||
posix_thread,
|
||||
sig_num,
|
||||
handler_addr,
|
||||
flags,
|
||||
@ -79,8 +91,11 @@ pub fn handle_pending_signal(
|
||||
mask,
|
||||
context,
|
||||
signal.to_info(),
|
||||
)?,
|
||||
)?
|
||||
}
|
||||
SigAction::Dfl => {
|
||||
drop(sig_dispositions);
|
||||
|
||||
let sig_default_action = SigDefaultAction::from_signum(sig_num);
|
||||
trace!("sig_default_action: {:?}", sig_default_action);
|
||||
match sig_default_action {
|
||||
@ -116,7 +131,9 @@ pub fn handle_pending_signal(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn handle_user_signal(
|
||||
posix_thread: &PosixThread,
|
||||
sig_num: SigNum,
|
||||
handler_addr: Vaddr,
|
||||
flags: SigActionFlags,
|
||||
@ -131,15 +148,14 @@ pub fn handle_user_signal(
|
||||
debug!("restorer_addr = 0x{:x}", restorer_addr);
|
||||
// FIXME: How to respect flags?
|
||||
if flags.contains_unsupported_flag() {
|
||||
println!("flags = {:?}", flags);
|
||||
panic!("Unsupported Signal flags");
|
||||
warn!("Unsupported Signal flags: {:?}", flags);
|
||||
}
|
||||
|
||||
if !flags.contains(SigActionFlags::SA_NODEFER) {
|
||||
// add current signal to mask
|
||||
mask += sig_num;
|
||||
}
|
||||
let current_thread = current_thread!();
|
||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
|
||||
// block signals in sigmask when running signal handler
|
||||
let old_mask = posix_thread.sig_mask().load(Ordering::Relaxed);
|
||||
posix_thread
|
||||
|
@ -103,11 +103,7 @@ impl SigActionFlags {
|
||||
}
|
||||
|
||||
pub fn contains_unsupported_flag(&self) -> bool {
|
||||
self.intersects(
|
||||
SigActionFlags::SA_NOCLDSTOP
|
||||
| SigActionFlags::SA_NOCLDWAIT
|
||||
| SigActionFlags::SA_RESETHAND,
|
||||
)
|
||||
self.intersects(SigActionFlags::SA_NOCLDSTOP | SigActionFlags::SA_NOCLDWAIT)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user