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