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