453 lines
14 KiB
Rust
453 lines
14 KiB
Rust
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;
|
||
}
|