xref: /DragonOS/kernel/src/arch/riscv64/ipc/signal.rs (revision 52da9a59374752b4d01907b052135a0d317781dd)
1 use crate::{
2     arch::{sched::sched, CurrentIrqArch},
3     exception::InterruptArch,
4     kerror,
5     process::ProcessManager,
6 };
7 
8 /// 信号处理的栈的栈指针的最小对齐数量
9 pub const STACK_ALIGN: u64 = 16;
10 /// 信号最大值
11 pub const MAX_SIG_NUM: usize = 64;
12 #[allow(dead_code)]
13 #[derive(Eq)]
14 #[repr(usize)]
15 #[allow(non_camel_case_types)]
16 #[atomic_enum]
17 pub enum Signal {
18     INVALID = 0,
19     SIGHUP = 1,
20     SIGINT,
21     SIGQUIT,
22     SIGILL,
23     SIGTRAP,
24     /// SIGABRT和SIGIOT共用这个号码
25     SIGABRT_OR_IOT,
26     SIGBUS,
27     SIGFPE,
28     SIGKILL,
29     SIGUSR1,
30 
31     SIGSEGV = 11,
32     SIGUSR2,
33     SIGPIPE,
34     SIGALRM,
35     SIGTERM,
36     SIGSTKFLT,
37     SIGCHLD,
38     SIGCONT,
39     SIGSTOP,
40     SIGTSTP,
41 
42     SIGTTIN = 21,
43     SIGTTOU,
44     SIGURG,
45     SIGXCPU,
46     SIGXFSZ,
47     SIGVTALRM,
48     SIGPROF,
49     SIGWINCH,
50     /// SIGIO和SIGPOLL共用这个号码
51     SIGIO_OR_POLL,
52     SIGPWR,
53 
54     SIGSYS = 31,
55 
56     SIGRTMIN = 32,
57     SIGRTMAX = 64,
58 }
59 
60 /// 为Signal实现判断相等的trait
61 impl PartialEq for Signal {
62     fn eq(&self, other: &Signal) -> bool {
63         *self as usize == *other as usize
64     }
65 }
66 
67 impl From<usize> for Signal {
68     fn from(value: usize) -> Self {
69         if value <= MAX_SIG_NUM {
70             let ret: Signal = unsafe { core::mem::transmute(value) };
71             return ret;
72         } else {
73             kerror!("Try to convert an invalid number to Signal");
74             return Signal::INVALID;
75         }
76     }
77 }
78 
79 impl Into<usize> for Signal {
80     fn into(self) -> usize {
81         self as usize
82     }
83 }
84 
85 impl From<i32> for Signal {
86     fn from(value: i32) -> Self {
87         if value < 0 {
88             kerror!("Try to convert an invalid number to Signal");
89             return Signal::INVALID;
90         } else {
91             return Self::from(value as usize);
92         }
93     }
94 }
95 
96 impl Into<SigSet> for Signal {
97     fn into(self) -> SigSet {
98         SigSet {
99             bits: (1 << (self as usize - 1) as u64),
100         }
101     }
102 }
103 impl Signal {
104     /// 判断一个数字是否为可用的信号
105     #[inline]
106     pub fn is_valid(&self) -> bool {
107         return (*self) as usize <= MAX_SIG_NUM;
108     }
109 
110     /// const convertor between `Signal` and `SigSet`
111     pub const fn into_sigset(self) -> SigSet {
112         SigSet {
113             bits: (1 << (self as usize - 1) as u64),
114         }
115     }
116 
117     /// 判断一个信号是不是实时信号
118     ///
119     /// ## 返回值
120     ///
121     /// - `true` 这个信号是实时信号
122     /// - `false` 这个信号不是实时信号
123     #[inline]
124     pub fn is_rt_signal(&self) -> bool {
125         return (*self) as usize >= Signal::SIGRTMIN.into();
126     }
127 
128     /// 调用信号的默认处理函数
129     pub fn handle_default(&self) {
130         match self {
131             Signal::INVALID => {
132                 kerror!("attempting to handler an Invalid");
133             }
134             Signal::SIGHUP => sig_terminate(self.clone()),
135             Signal::SIGINT => sig_terminate(self.clone()),
136             Signal::SIGQUIT => sig_terminate_dump(self.clone()),
137             Signal::SIGILL => sig_terminate_dump(self.clone()),
138             Signal::SIGTRAP => sig_terminate_dump(self.clone()),
139             Signal::SIGABRT_OR_IOT => sig_terminate_dump(self.clone()),
140             Signal::SIGBUS => sig_terminate_dump(self.clone()),
141             Signal::SIGFPE => sig_terminate_dump(self.clone()),
142             Signal::SIGKILL => sig_terminate(self.clone()),
143             Signal::SIGUSR1 => sig_terminate(self.clone()),
144             Signal::SIGSEGV => sig_terminate_dump(self.clone()),
145             Signal::SIGUSR2 => sig_terminate(self.clone()),
146             Signal::SIGPIPE => sig_terminate(self.clone()),
147             Signal::SIGALRM => sig_terminate(self.clone()),
148             Signal::SIGTERM => sig_terminate(self.clone()),
149             Signal::SIGSTKFLT => sig_terminate(self.clone()),
150             Signal::SIGCHLD => sig_ignore(self.clone()),
151             Signal::SIGCONT => sig_continue(self.clone()),
152             Signal::SIGSTOP => sig_stop(self.clone()),
153             Signal::SIGTSTP => sig_stop(self.clone()),
154             Signal::SIGTTIN => sig_stop(self.clone()),
155             Signal::SIGTTOU => sig_stop(self.clone()),
156             Signal::SIGURG => sig_ignore(self.clone()),
157             Signal::SIGXCPU => sig_terminate_dump(self.clone()),
158             Signal::SIGXFSZ => sig_terminate_dump(self.clone()),
159             Signal::SIGVTALRM => sig_terminate(self.clone()),
160             Signal::SIGPROF => sig_terminate(self.clone()),
161             Signal::SIGWINCH => sig_ignore(self.clone()),
162             Signal::SIGIO_OR_POLL => sig_terminate(self.clone()),
163             Signal::SIGPWR => sig_terminate(self.clone()),
164             Signal::SIGSYS => sig_terminate(self.clone()),
165             Signal::SIGRTMIN => sig_terminate(self.clone()),
166             Signal::SIGRTMAX => sig_terminate(self.clone()),
167         }
168     }
169 }
170 
171 /// siginfo中的si_code的可选值
172 /// 请注意,当这个值小于0时,表示siginfo来自用户态,否则来自内核态
173 #[derive(Copy, Debug, Clone)]
174 #[repr(i32)]
175 pub enum SigCode {
176     /// sent by kill, sigsend, raise
177     User = 0,
178     /// sent by kernel from somewhere
179     Kernel = 0x80,
180     /// 通过sigqueue发送
181     Queue = -1,
182     /// 定时器过期时发送
183     Timer = -2,
184     /// 当实时消息队列的状态发生改变时发送
185     Mesgq = -3,
186     /// 当异步IO完成时发送
187     AsyncIO = -4,
188     /// sent by queued SIGIO
189     SigIO = -5,
190 }
191 
192 impl SigCode {
193     /// 为SigCode这个枚举类型实现从i32转换到枚举类型的转换函数
194     #[allow(dead_code)]
195     pub fn from_i32(x: i32) -> SigCode {
196         match x {
197             0 => Self::User,
198             0x80 => Self::Kernel,
199             -1 => Self::Queue,
200             -2 => Self::Timer,
201             -3 => Self::Mesgq,
202             -4 => Self::AsyncIO,
203             -5 => Self::SigIO,
204             _ => panic!("signal code not valid"),
205         }
206     }
207 }
208 
209 bitflags! {
210     #[repr(C,align(8))]
211     #[derive(Default)]
212     pub struct SigFlags:u32{
213         const SA_NOCLDSTOP =  1;
214         const SA_NOCLDWAIT = 2;
215         const SA_SIGINFO   = 4;
216         const SA_ONSTACK   = 0x08000000;
217         const SA_RESTART   = 0x10000000;
218         const SA_NODEFER  = 0x40000000;
219         const SA_RESETHAND = 0x80000000;
220         const SA_RESTORER   =0x04000000;
221         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();
222     }
223 
224     /// 请注意,sigset 这个bitmap, 第0位表示sig=1的信号。也就是说,Signal-1才是sigset_t中对应的位
225     #[derive(Default)]
226     pub struct SigSet:u64{
227         const SIGHUP   =  1<<0;
228         const SIGINT   =  1<<1;
229         const SIGQUIT  =  1<<2;
230         const SIGILL   =  1<<3;
231         const SIGTRAP  =  1<<4;
232         /// SIGABRT和SIGIOT共用这个号码
233         const SIGABRT_OR_IOT    =    1<<5;
234         const SIGBUS   =  1<<6;
235         const SIGFPE   =  1<<7;
236         const SIGKILL  =  1<<8;
237         const SIGUSR   =  1<<9;
238         const SIGSEGV  =  1<<10;
239         const SIGUSR2  =  1<<11;
240         const SIGPIPE  =  1<<12;
241         const SIGALRM  =  1<<13;
242         const SIGTERM  =  1<<14;
243         const SIGSTKFLT=  1<<15;
244         const SIGCHLD  =  1<<16;
245         const SIGCONT  =  1<<17;
246         const SIGSTOP  =  1<<18;
247         const SIGTSTP  =  1<<19;
248         const SIGTTIN  =  1<<20;
249         const SIGTTOU  =  1<<21;
250         const SIGURG   =  1<<22;
251         const SIGXCPU  =  1<<23;
252         const SIGXFSZ  =  1<<24;
253         const SIGVTALRM=  1<<25;
254         const SIGPROF  =  1<<26;
255         const SIGWINCH =  1<<27;
256         /// SIGIO和SIGPOLL共用这个号码
257         const SIGIO_OR_POLL    =   1<<28;
258         const SIGPWR   =  1<<29;
259         const SIGSYS   =  1<<30;
260         const SIGRTMIN =  1<<31;
261         // TODO 写上实时信号
262         const SIGRTMAX =  1<<MAX_SIG_NUM-1;
263     }
264 }
265 
266 /// SIGCHLD si_codes
267 #[derive(Debug, Clone, Copy, PartialEq, Eq, ToPrimitive)]
268 #[allow(dead_code)]
269 pub enum SigChildCode {
270     /// child has exited
271     ///
272     /// CLD_EXITED
273     Exited = 1,
274     /// child was killed
275     ///
276     /// CLD_KILLED
277     Killed = 2,
278     /// child terminated abnormally
279     ///
280     /// CLD_DUMPED
281     Dumped = 3,
282     /// traced child has trapped
283     ///
284     /// CLD_TRAPPED
285     Trapped = 4,
286     /// child has stopped
287     ///
288     /// CLD_STOPPED
289     Stopped = 5,
290     /// stopped child has continued
291     ///
292     /// CLD_CONTINUED
293     Continued = 6,
294 }
295 
296 impl Into<i32> for SigChildCode {
297     fn into(self) -> i32 {
298         self as i32
299     }
300 }
301 
302 /// 信号默认处理函数——终止进程
303 fn sig_terminate(sig: Signal) {
304     ProcessManager::exit(sig as usize);
305 }
306 
307 /// 信号默认处理函数——终止进程并生成 core dump
308 fn sig_terminate_dump(sig: Signal) {
309     ProcessManager::exit(sig as usize);
310     // TODO 生成 coredump 文件
311 }
312 
313 /// 信号默认处理函数——暂停进程
314 fn sig_stop(sig: Signal) {
315     let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
316     ProcessManager::mark_stop().unwrap_or_else(|e| {
317         kerror!(
318             "sleep error :{:?},failed to sleep process :{:?}, with signal :{:?}",
319             e,
320             ProcessManager::current_pcb(),
321             sig
322         );
323     });
324     drop(guard);
325     sched();
326     // TODO 暂停进程
327 }
328 
329 /// 信号默认处理函数——继续进程
330 fn sig_continue(sig: Signal) {
331     ProcessManager::wakeup_stop(&ProcessManager::current_pcb()).unwrap_or_else(|_| {
332         kerror!(
333             "Failed to wake up process pid = {:?} with signal :{:?}",
334             ProcessManager::current_pcb().pid(),
335             sig
336         );
337     });
338 }
339 /// 信号默认处理函数——忽略
340 fn sig_ignore(_sig: Signal) {
341     return;
342 }
343