DragonOS/kernel/src/ipc/generic_signal.rs

453 lines
14 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use num_traits::FromPrimitive;
use crate::ipc::signal_types::SignalFlags;
use crate::{
arch::{
ipc::signal::{SigSet, Signal, MAX_SIG_NUM},
CurrentIrqArch,
},
exception::InterruptArch,
process::ProcessManager,
sched::{schedule, SchedMode},
};
/// 信号处理的栈的栈指针的最小对齐
#[allow(dead_code)]
pub const GENERIC_STACK_ALIGN: u64 = 16;
/// 信号最大值
#[allow(dead_code)]
pub const GENERIC_MAX_SIG_NUM: usize = 64;
#[allow(dead_code)]
#[derive(Eq, PartialEq, FromPrimitive)]
#[repr(usize)]
#[allow(non_camel_case_types)]
#[atomic_enum]
pub enum GenericSignal {
INVALID = 0,
SIGHUP = 1,
SIGINT,
SIGQUIT,
SIGILL,
SIGTRAP,
/// SIGABRT和SIGIOT共用这个号码
SIGABRT_OR_IOT,
SIGBUS,
SIGFPE,
SIGKILL,
SIGUSR1,
SIGSEGV = 11,
SIGUSR2,
SIGPIPE,
SIGALRM,
SIGTERM,
SIGSTKFLT,
SIGCHLD,
SIGCONT,
SIGSTOP,
SIGTSTP,
SIGTTIN = 21,
SIGTTOU,
SIGURG,
SIGXCPU,
SIGXFSZ,
SIGVTALRM,
SIGPROF,
SIGWINCH,
/// SIGIO和SIGPOLL共用这个号码
SIGIO_OR_POLL,
SIGPWR,
SIGSYS = 31,
SIGRTMIN = 32,
// 实时信号SIGRTMIN+1 到 SIGRTMAX-1
SIGRTMIN_1 = 33,
SIGRTMIN_2 = 34,
SIGRTMIN_3 = 35,
SIGRTMIN_4 = 36,
SIGRTMIN_5 = 37,
SIGRTMIN_6 = 38,
SIGRTMIN_7 = 39,
SIGRTMIN_8 = 40,
SIGRTMIN_9 = 41,
SIGRTMIN_10 = 42,
SIGRTMIN_11 = 43,
SIGRTMIN_12 = 44,
SIGRTMIN_13 = 45,
SIGRTMIN_14 = 46,
SIGRTMIN_15 = 47,
SIGRTMIN_16 = 48,
SIGRTMIN_17 = 49,
SIGRTMIN_18 = 50,
SIGRTMIN_19 = 51,
SIGRTMIN_20 = 52,
SIGRTMIN_21 = 53,
SIGRTMIN_22 = 54,
SIGRTMIN_23 = 55,
SIGRTMIN_24 = 56,
SIGRTMIN_25 = 57,
SIGRTMIN_26 = 58,
SIGRTMIN_27 = 59,
SIGRTMIN_28 = 60,
SIGRTMIN_29 = 61,
SIGRTMIN_30 = 62,
SIGRTMIN_31 = 63,
SIGRTMAX = 64,
}
impl GenericSignal {
/// 判断一个数字是否为可用的信号
#[inline]
pub fn is_valid(&self) -> bool {
return (*self) as usize <= MAX_SIG_NUM;
}
/// const convertor between `Signal` and `SigSet`
pub const fn into_sigset(self) -> SigSet {
SigSet::from_bits_truncate(1 << (self as usize - 1))
}
/// 判断一个信号是不是实时信号
///
/// ## 返回值
///
/// - `true` 这个信号是实时信号
/// - `false` 这个信号不是实时信号
#[inline]
pub fn is_rt_signal(&self) -> bool {
return (*self) as usize >= Self::SIGRTMIN.into();
}
/// 判断一个信号号是否为实时信号
#[inline]
pub fn is_rt_signal_number(sig_num: i32) -> bool {
sig_num >= Self::SIGRTMIN as i32 && sig_num <= Self::SIGRTMAX as i32
}
/// 获取实时信号的范围
#[inline]
pub fn rt_signal_range() -> (i32, i32) {
(Self::SIGRTMIN as i32, Self::SIGRTMAX as i32)
}
/// 调用信号的默认处理函数
pub fn handle_default(&self) {
match self {
Self::INVALID => {
log::error!("attempting to handler an Invalid");
}
Self::SIGHUP => sig_terminate(*self),
Self::SIGINT => sig_terminate(*self),
Self::SIGQUIT => sig_terminate_dump(*self),
Self::SIGILL => sig_terminate_dump(*self),
Self::SIGTRAP => sig_terminate_dump(*self),
Self::SIGABRT_OR_IOT => sig_terminate_dump(*self),
Self::SIGBUS => sig_terminate_dump(*self),
Self::SIGFPE => sig_terminate_dump(*self),
Self::SIGKILL => sig_terminate(*self),
Self::SIGUSR1 => sig_terminate(*self),
Self::SIGSEGV => sig_terminate_dump(*self),
Self::SIGUSR2 => sig_terminate(*self),
Self::SIGPIPE => sig_terminate(*self),
Self::SIGALRM => sig_terminate(*self),
Self::SIGTERM => sig_terminate(*self),
Self::SIGSTKFLT => sig_terminate(*self),
Self::SIGCHLD => sig_ignore(*self),
Self::SIGCONT => sig_continue(*self),
Self::SIGSTOP => sig_stop(*self),
Self::SIGTSTP => sig_stop(*self),
Self::SIGTTIN => sig_stop(*self),
Self::SIGTTOU => sig_stop(*self),
Self::SIGURG => sig_ignore(*self),
Self::SIGXCPU => sig_terminate_dump(*self),
Self::SIGXFSZ => sig_terminate_dump(*self),
Self::SIGVTALRM => sig_terminate(*self),
Self::SIGPROF => sig_terminate(*self),
Self::SIGWINCH => sig_ignore(*self),
Self::SIGIO_OR_POLL => sig_terminate(*self),
Self::SIGPWR => sig_terminate(*self),
Self::SIGSYS => sig_terminate(*self),
// 实时信号默认处理:终止进程
Self::SIGRTMIN => sig_terminate(*self),
Self::SIGRTMIN_1 => sig_terminate(*self),
Self::SIGRTMIN_2 => sig_terminate(*self),
Self::SIGRTMIN_3 => sig_terminate(*self),
Self::SIGRTMIN_4 => sig_terminate(*self),
Self::SIGRTMIN_5 => sig_terminate(*self),
Self::SIGRTMIN_6 => sig_terminate(*self),
Self::SIGRTMIN_7 => sig_terminate(*self),
Self::SIGRTMIN_8 => sig_terminate(*self),
Self::SIGRTMIN_9 => sig_terminate(*self),
Self::SIGRTMIN_10 => sig_terminate(*self),
Self::SIGRTMIN_11 => sig_terminate(*self),
Self::SIGRTMIN_12 => sig_terminate(*self),
Self::SIGRTMIN_13 => sig_terminate(*self),
Self::SIGRTMIN_14 => sig_terminate(*self),
Self::SIGRTMIN_15 => sig_terminate(*self),
Self::SIGRTMIN_16 => sig_terminate(*self),
Self::SIGRTMIN_17 => sig_terminate(*self),
Self::SIGRTMIN_18 => sig_terminate(*self),
Self::SIGRTMIN_19 => sig_terminate(*self),
Self::SIGRTMIN_20 => sig_terminate(*self),
Self::SIGRTMIN_21 => sig_terminate(*self),
Self::SIGRTMIN_22 => sig_terminate(*self),
Self::SIGRTMIN_23 => sig_terminate(*self),
Self::SIGRTMIN_24 => sig_terminate(*self),
Self::SIGRTMIN_25 => sig_terminate(*self),
Self::SIGRTMIN_26 => sig_terminate(*self),
Self::SIGRTMIN_27 => sig_terminate(*self),
Self::SIGRTMIN_28 => sig_terminate(*self),
Self::SIGRTMIN_29 => sig_terminate(*self),
Self::SIGRTMIN_30 => sig_terminate(*self),
Self::SIGRTMIN_31 => sig_terminate(*self),
Self::SIGRTMAX => sig_terminate(*self),
}
}
pub fn kernel_only(&self) -> bool {
matches!(self, Self::SIGKILL | Self::SIGSTOP)
}
}
impl From<GenericSignal> for usize {
fn from(val: GenericSignal) -> Self {
val as usize
}
}
impl From<usize> for GenericSignal {
fn from(value: usize) -> Self {
<Self as FromPrimitive>::from_usize(value).unwrap_or(GenericSignal::INVALID)
}
}
impl From<i32> for GenericSignal {
fn from(value: i32) -> Self {
if value < 0 {
log::error!(
"Try to convert a negative number {} to GenericSignal",
value
);
return GenericSignal::INVALID;
} else if value as usize > GENERIC_MAX_SIG_NUM {
log::error!(
"Try to convert an out-of-range number {} to GenericSignal (max: {})",
value,
GENERIC_MAX_SIG_NUM
);
return GenericSignal::INVALID;
} else {
return Self::from(value as usize);
}
}
}
impl From<GenericSignal> for GenericSigSet {
fn from(val: GenericSignal) -> Self {
GenericSigSet {
bits: (1 << (val as usize - 1) as u64),
}
}
}
/// SIGCHLD si_codes
#[derive(Debug, Clone, Copy, PartialEq, Eq, ToPrimitive)]
#[allow(dead_code)]
pub enum GenericSigChildCode {
/// child has exited
///
/// CLD_EXITED
Exited = 1,
/// child was killed
///
/// CLD_KILLED
Killed = 2,
/// child terminated abnormally
///
/// CLD_DUMPED
Dumped = 3,
/// traced child has trapped
///
/// CLD_TRAPPED
Trapped = 4,
/// child has stopped
///
/// CLD_STOPPED
Stopped = 5,
/// stopped child has continued
///
/// CLD_CONTINUED
Continued = 6,
}
impl From<GenericSigChildCode> for i32 {
fn from(value: GenericSigChildCode) -> Self {
value as i32
}
}
bitflags! {
/// 请注意sigset 这个bitmap, 第0位表示sig=1的信号。也就是说Signal-1才是sigset_t中对应的位
#[derive(Default)]
pub struct GenericSigSet:u64 {
const SIGHUP = 1<<0;
const SIGINT = 1<<1;
const SIGQUIT = 1<<2;
const SIGILL = 1<<3;
const SIGTRAP = 1<<4;
/// SIGABRT和SIGIOT共用这个号码
const SIGABRT_OR_IOT = 1<<5;
const SIGBUS = 1<<6;
const SIGFPE = 1<<7;
const SIGKILL = 1<<8;
const SIGUSR = 1<<9;
const SIGSEGV = 1<<10;
const SIGUSR2 = 1<<11;
const SIGPIPE = 1<<12;
const SIGALRM = 1<<13;
const SIGTERM = 1<<14;
const SIGSTKFLT= 1<<15;
const SIGCHLD = 1<<16;
const SIGCONT = 1<<17;
const SIGSTOP = 1<<18;
const SIGTSTP = 1<<19;
const SIGTTIN = 1<<20;
const SIGTTOU = 1<<21;
const SIGURG = 1<<22;
const SIGXCPU = 1<<23;
const SIGXFSZ = 1<<24;
const SIGVTALRM= 1<<25;
const SIGPROF = 1<<26;
const SIGWINCH = 1<<27;
/// SIGIO和SIGPOLL共用这个号码
const SIGIO_OR_POLL = 1<<28;
const SIGPWR = 1<<29;
const SIGSYS = 1<<30;
const SIGRTMIN = 1<<31;
// 实时信号位图SIGRTMIN+1 到 SIGRTMAX-1
const SIGRTMIN_1 = 1<<32;
const SIGRTMIN_2 = 1<<33;
const SIGRTMIN_3 = 1<<34;
const SIGRTMIN_4 = 1<<35;
const SIGRTMIN_5 = 1<<36;
const SIGRTMIN_6 = 1<<37;
const SIGRTMIN_7 = 1<<38;
const SIGRTMIN_8 = 1<<39;
const SIGRTMIN_9 = 1<<40;
const SIGRTMIN_10 = 1<<41;
const SIGRTMIN_11 = 1<<42;
const SIGRTMIN_12 = 1<<43;
const SIGRTMIN_13 = 1<<44;
const SIGRTMIN_14 = 1<<45;
const SIGRTMIN_15 = 1<<46;
const SIGRTMIN_16 = 1<<47;
const SIGRTMIN_17 = 1<<48;
const SIGRTMIN_18 = 1<<49;
const SIGRTMIN_19 = 1<<50;
const SIGRTMIN_20 = 1<<51;
const SIGRTMIN_21 = 1<<52;
const SIGRTMIN_22 = 1<<53;
const SIGRTMIN_23 = 1<<54;
const SIGRTMIN_24 = 1<<55;
const SIGRTMIN_25 = 1<<56;
const SIGRTMIN_26 = 1<<57;
const SIGRTMIN_27 = 1<<58;
const SIGRTMIN_28 = 1<<59;
const SIGRTMIN_29 = 1<<60;
const SIGRTMIN_30 = 1<<61;
const SIGRTMIN_31 = 1<<62;
const SIGRTMAX = 1<<63;
}
#[repr(C,align(8))]
#[derive(Default)]
pub struct GenericSigFlags:u32{
const SA_NOCLDSTOP = 1;
const SA_NOCLDWAIT = 2;
const SA_SIGINFO = 4;
const SA_ONSTACK = 0x08000000;
const SA_RESTART = 0x10000000;
const SA_NODEFER = 0x40000000;
const SA_RESETHAND = 0x80000000;
const SA_RESTORER =0x04000000;
const SA_ALL = Self::SA_NOCLDSTOP.bits()|Self::SA_NOCLDWAIT.bits()|Self::SA_NODEFER.bits()|Self::SA_ONSTACK.bits()|Self::SA_RESETHAND.bits()|Self::SA_RESTART.bits()|Self::SA_SIGINFO.bits()|Self::SA_RESTORER.bits();
}
}
bitflags! {
#[repr(C)]
#[derive(Default)]
pub struct GenericSigStackFlags:u32{
const SS_ONSTACK = 1;
const SS_DISABLE = 2;
const SS_AUTODISARM = 1 << 31;
}
}
/// 信号默认处理函数——终止进程
fn sig_terminate(sig: Signal) {
ProcessManager::exit(sig as usize);
}
/// 信号默认处理函数——终止进程并生成 core dump
fn sig_terminate_dump(sig: Signal) {
ProcessManager::exit(sig as usize);
// TODO 生成 coredump 文件
}
/// 信号默认处理函数——暂停进程
fn sig_stop(sig: Signal) {
// 在接收者上下文设置停止标志,并让当前任务进入 Stopped
let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
{
let pcb = ProcessManager::current_pcb();
// 标记停止事件,供 waitid(WSTOPPED) 可见
pcb.sighand().flags_insert(SignalFlags::CLD_STOPPED);
pcb.sighand().flags_insert(SignalFlags::STOP_STOPPED);
}
ProcessManager::mark_stop().unwrap_or_else(|e| {
log::error!(
"sleep error :{:?},failed to sleep process :{:?}, with signal :{:?}",
e,
ProcessManager::current_pcb().pid(),
sig
);
});
drop(guard);
log::debug!(
"sig_stop: pid={:?} entered Stopped; notifying parent and scheduler",
ProcessManager::current_pcb().raw_pid()
);
// 向父进程报告 SIGCHLD 并唤醒父进程可能阻塞的 wait
let pcb = ProcessManager::current_pcb();
if let Some(parent) = pcb.parent_pcb() {
let _ = crate::ipc::kill::kill_process_by_pcb(parent.clone(), Signal::SIGCHLD);
parent.wake_all_waiters();
}
// 唤醒等待在该子进程等待队列上的等待者
pcb.wake_all_waiters();
schedule(SchedMode::SM_NONE);
}
/// 信号默认处理函数——继续进程
fn sig_continue(_sig: Signal) {
// 默认处理改为最小化:仅在已处于 Stopped 时唤醒停止,让进程继续运行。
let pcb = ProcessManager::current_pcb();
let is_stopped = pcb
.sched_info()
.inner_lock_read_irqsave()
.state()
.is_stopped();
if is_stopped {
let _ = ProcessManager::wakeup_stop(&pcb);
}
// 标志位设置与父进程通知统一由 prepare_signal(SIGCONT) 路径处理,避免重复/竞态
}
/// 信号默认处理函数——忽略
fn sig_ignore(_sig: Signal) {
return;
}