xref: /DragonOS/kernel/src/ipc/signal_types.rs (revision d8e29bffeee4fe4fe76ead3c761dd03f5395e6c2)
1 use core::{
2     ffi::c_void,
3     mem::size_of,
4     ops::{Deref, DerefMut},
5     sync::atomic::AtomicI64,
6 };
7 
8 use alloc::{boxed::Box, vec::Vec};
9 use system_error::SystemError;
10 
11 use crate::{
12     arch::{
13         asm::bitops::ffz,
14         interrupt::TrapFrame,
15         ipc::signal::{SigCode, SigFlags, SigSet, Signal, MAX_SIG_NUM},
16     },
17     mm::VirtAddr,
18     process::Pid,
19     syscall::user_access::UserBufferWriter,
20 };
21 
22 /// 用户态程序传入的SIG_DFL的值
23 pub const USER_SIG_DFL: u64 = 0;
24 /// 用户态程序传入的SIG_IGN的值
25 pub const USER_SIG_IGN: u64 = 1;
26 /// 用户态程序传入的SIG_ERR的值
27 pub const USER_SIG_ERR: u64 = 2;
28 
29 // 因为 Rust 编译器不能在常量声明中正确识别级联的 "|" 运算符(experimental feature: https://github.com/rust-lang/rust/issues/67792),因此
30 // 暂时只能通过这种方法来声明这些常量,这些常量暂时没有全部用到,但是都出现在 linux 的判断逻辑中,所以都保留下来了
31 #[allow(dead_code)]
32 pub const SIG_KERNEL_ONLY_MASK: SigSet =
33     Signal::into_sigset(Signal::SIGSTOP).union(Signal::into_sigset(Signal::SIGKILL));
34 
35 pub const SIG_KERNEL_STOP_MASK: SigSet = Signal::into_sigset(Signal::SIGSTOP)
36     .union(Signal::into_sigset(Signal::SIGTSTP))
37     .union(Signal::into_sigset(Signal::SIGTTIN))
38     .union(Signal::into_sigset(Signal::SIGTTOU));
39 #[allow(dead_code)]
40 pub const SIG_KERNEL_COREDUMP_MASK: SigSet = Signal::into_sigset(Signal::SIGQUIT)
41     .union(Signal::into_sigset(Signal::SIGILL))
42     .union(Signal::into_sigset(Signal::SIGTRAP))
43     .union(Signal::into_sigset(Signal::SIGABRT_OR_IOT))
44     .union(Signal::into_sigset(Signal::SIGFPE))
45     .union(Signal::into_sigset(Signal::SIGSEGV))
46     .union(Signal::into_sigset(Signal::SIGBUS))
47     .union(Signal::into_sigset(Signal::SIGSYS))
48     .union(Signal::into_sigset(Signal::SIGXCPU))
49     .union(Signal::into_sigset(Signal::SIGXFSZ));
50 #[allow(dead_code)]
51 pub const SIG_KERNEL_IGNORE_MASK: SigSet = Signal::into_sigset(Signal::SIGCONT)
52     .union(Signal::into_sigset(Signal::SIGFPE))
53     .union(Signal::into_sigset(Signal::SIGSEGV))
54     .union(Signal::into_sigset(Signal::SIGBUS))
55     .union(Signal::into_sigset(Signal::SIGTRAP))
56     .union(Signal::into_sigset(Signal::SIGCHLD))
57     .union(Signal::into_sigset(Signal::SIGIO_OR_POLL))
58     .union(Signal::into_sigset(Signal::SIGSYS));
59 
60 /// SignalStruct 在 pcb 中加锁
61 #[derive(Debug)]
62 pub struct SignalStruct {
63     inner: Box<InnerSignalStruct>,
64 }
65 
66 #[derive(Debug)]
67 pub struct InnerSignalStruct {
68     pub cnt: AtomicI64,
69     /// 如果对应linux,这部分会有一个引用计数,但是没发现在哪里有用到需要计算引用的地方,因此
70     /// 暂时删掉,不然这个Arc会导致其他地方的代码十分丑陋
71     pub handlers: [Sigaction; MAX_SIG_NUM as usize],
72 }
73 
74 impl SignalStruct {
75     #[inline(never)]
76     pub fn new() -> Self {
77         Self {
78             inner: Box::new(InnerSignalStruct::default()),
79         }
80     }
81 }
82 
83 impl Deref for SignalStruct {
84     type Target = InnerSignalStruct;
85 
86     fn deref(&self) -> &Self::Target {
87         &self.inner
88     }
89 }
90 
91 impl DerefMut for SignalStruct {
92     fn deref_mut(&mut self) -> &mut Self::Target {
93         &mut self.inner
94     }
95 }
96 
97 impl Default for InnerSignalStruct {
98     fn default() -> Self {
99         Self {
100             cnt: Default::default(),
101             handlers: [Sigaction::default(); MAX_SIG_NUM as usize],
102         }
103     }
104 }
105 
106 #[derive(Debug, Copy, Clone)]
107 #[allow(dead_code)]
108 pub enum SigactionType {
109     SaHandler(SaHandlerType),
110     SaSigaction(
111         Option<
112             unsafe extern "C" fn(
113                 sig: ::core::ffi::c_int,
114                 sinfo: *mut SigInfo,
115                 arg1: *mut ::core::ffi::c_void,
116             ),
117         >,
118     ), // 暂时没有用上
119 }
120 
121 impl SigactionType {
122     /// Returns `true` if the sa handler type is [`SaHandler(SaHandlerType::SigIgnore)`].
123     ///
124     /// [`SigIgnore`]: SaHandlerType::SigIgnore
125     pub fn is_ignore(&self) -> bool {
126         return matches!(self, Self::SaHandler(SaHandlerType::SigIgnore));
127     }
128     /// Returns `true` if the sa handler type is [`SaHandler(SaHandlerType::SigCustomized(_))`].
129     ///
130     /// [`SigCustomized`]: SaHandlerType::SigCustomized(_)
131     pub fn is_customized(&self) -> bool {
132         return matches!(self, Self::SaHandler(SaHandlerType::SigCustomized(_)));
133     }
134 }
135 
136 #[derive(Debug, Copy, Clone)]
137 #[allow(dead_code)]
138 pub enum SaHandlerType {
139     SigError, // 暂时没有用上
140     SigDefault,
141     SigIgnore,
142     SigCustomized(VirtAddr),
143 }
144 
145 impl Into<usize> for SaHandlerType {
146     fn into(self) -> usize {
147         match self {
148             Self::SigError => 2 as usize,
149             Self::SigIgnore => 1 as usize,
150             Self::SigDefault => 0 as usize,
151             Self::SigCustomized(handler) => handler.data(),
152         }
153     }
154 }
155 
156 impl SaHandlerType {
157     /// Returns `true` if the sa handler type is [`SigDefault`].
158     ///
159     /// [`SigDefault`]: SaHandlerType::SigDefault
160     pub fn is_sig_default(&self) -> bool {
161         matches!(self, Self::SigDefault)
162     }
163 
164     /// Returns `true` if the sa handler type is [`SigIgnore`].
165     ///
166     /// [`SigIgnore`]: SaHandlerType::SigIgnore
167     pub fn is_sig_ignore(&self) -> bool {
168         matches!(self, Self::SigIgnore)
169     }
170 
171     /// Returns `true` if the sa handler type is [`SigError`].
172     ///
173     /// [`SigError`]: SaHandlerType::SigError
174     pub fn is_sig_error(&self) -> bool {
175         matches!(self, Self::SigError)
176     }
177 }
178 
179 /// 信号处理结构体
180 ///
181 #[derive(Debug, Copy, Clone)]
182 pub struct Sigaction {
183     action: SigactionType,
184     flags: SigFlags,
185     mask: SigSet, // 为了可扩展性而设置的sa_mask
186     /// 信号处理函数执行结束后,将会跳转到这个函数内进行执行,然后执行sigreturn系统调用
187     restorer: Option<VirtAddr>,
188 }
189 
190 impl Default for Sigaction {
191     fn default() -> Self {
192         Self {
193             action: SigactionType::SaHandler(SaHandlerType::SigDefault),
194             flags: Default::default(),
195             mask: Default::default(),
196             restorer: Default::default(),
197         }
198     }
199 }
200 
201 impl Sigaction {
202     /// 判断传入的信号是否被忽略
203     ///
204     /// ## 参数
205     ///
206     /// - `sig` 传入的信号
207     ///
208     /// ## 返回值
209     ///
210     /// - `true` 被忽略
211     /// - `false`未被忽略
212     pub fn is_ignore(&self) -> bool {
213         return self.action.is_ignore();
214     }
215     pub fn new(
216         action: SigactionType,
217         flags: SigFlags,
218         mask: SigSet,
219         restorer: Option<VirtAddr>,
220     ) -> Self {
221         Self {
222             action,
223             flags,
224             mask,
225             restorer,
226         }
227     }
228 
229     pub fn action(&self) -> SigactionType {
230         self.action
231     }
232 
233     pub fn flags(&self) -> SigFlags {
234         self.flags
235     }
236 
237     pub fn restorer(&self) -> Option<VirtAddr> {
238         self.restorer
239     }
240 
241     pub fn flags_mut(&mut self) -> &mut SigFlags {
242         &mut self.flags
243     }
244 
245     pub fn set_action(&mut self, action: SigactionType) {
246         self.action = action;
247     }
248 
249     pub fn mask(&self) -> SigSet {
250         self.mask
251     }
252 
253     pub fn mask_mut(&mut self) -> &mut SigSet {
254         &mut self.mask
255     }
256 
257     pub fn set_restorer(&mut self, restorer: Option<VirtAddr>) {
258         self.restorer = restorer;
259     }
260 
261     /// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位)
262     pub const DEFAULT_SIGACTION: Sigaction = Sigaction {
263         action: SigactionType::SaHandler(SaHandlerType::SigDefault),
264         flags: SigFlags::empty(),
265         mask: SigSet::from_bits_truncate(0),
266         restorer: None,
267     };
268 
269     /// 默认的“忽略信号”的sigaction
270     pub const DEFAULT_SIGACTION_IGNORE: Sigaction = Sigaction {
271         action: SigactionType::SaHandler(SaHandlerType::SigIgnore),
272         flags: SigFlags::empty(),
273         mask: SigSet::from_bits_truncate(0),
274         restorer: None,
275     };
276 }
277 
278 /// 用户态传入的sigaction结构体(符合posix规范)
279 /// 请注意,我们会在sys_sigaction函数里面将其转换成内核使用的sigaction结构体
280 #[repr(C)]
281 #[derive(Debug, Clone, Copy)]
282 pub struct UserSigaction {
283     pub handler: *mut core::ffi::c_void,
284     pub flags: SigFlags,
285     pub restorer: *mut core::ffi::c_void,
286     pub mask: SigSet,
287 }
288 
289 /**
290  * siginfo中,根据signal的来源不同,该info中对应了不同的数据./=
291  * 请注意,该info最大占用16字节
292  */
293 
294 #[repr(C)]
295 #[derive(Copy, Clone, Debug)]
296 pub struct SigInfo {
297     sig_no: i32,
298     sig_code: SigCode,
299     errno: i32,
300     sig_type: SigType,
301 }
302 
303 impl SigInfo {
304     pub fn sig_code(&self) -> SigCode {
305         self.sig_code
306     }
307 
308     pub fn set_sig_type(&mut self, sig_type: SigType) {
309         self.sig_type = sig_type;
310     }
311     /// @brief 将siginfo结构体拷贝到用户栈
312     /// ## 参数
313     ///
314     /// `to` 用户空间指针
315     ///
316     /// ## 注意
317     ///
318     /// 该函数对应Linux中的https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#3323
319     /// Linux还提供了 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#3383 用来实现
320     /// kernel_siginfo 保存到 用户的 compact_siginfo 的功能,但是我们系统内还暂时没有对这两种
321     /// siginfo做区分,因此暂时不需要第二个函数
322     pub fn copy_siginfo_to_user(&self, to: *mut SigInfo) -> Result<i32, SystemError> {
323         // 验证目标地址是否为用户空间
324         let mut user_buffer = UserBufferWriter::new(to, size_of::<SigInfo>(), true)?;
325 
326         let retval: Result<i32, SystemError> = Ok(0);
327 
328         user_buffer.copy_one_to_user(self, 0)?;
329         return retval;
330     }
331 }
332 
333 #[derive(Copy, Clone, Debug)]
334 pub enum SigType {
335     Kill(Pid),
336     // 后续完善下列中的具体字段
337     // Timer,
338     // Rt,
339     // SigChild,
340     // SigFault,
341     // SigPoll,
342     // SigSys,
343 }
344 
345 impl SigInfo {
346     pub fn new(sig: Signal, sig_errno: i32, sig_code: SigCode, sig_type: SigType) -> Self {
347         Self {
348             sig_no: sig as i32,
349             sig_code,
350             errno: sig_errno,
351             sig_type,
352         }
353     }
354 }
355 
356 #[derive(Debug)]
357 pub struct SigPending {
358     signal: SigSet,
359     queue: SigQueue,
360 }
361 
362 impl Default for SigPending {
363     fn default() -> Self {
364         SigPending {
365             signal: SigSet::default(),
366             queue: SigQueue::default(),
367         }
368     }
369 }
370 
371 impl SigPending {
372     /// 判断是否有待处理的信号
373     pub fn has_pending(&self) -> bool {
374         return !self.signal.is_empty();
375     }
376 
377     pub fn signal(&self) -> SigSet {
378         self.signal
379     }
380 
381     pub fn queue(&self) -> &SigQueue {
382         &self.queue
383     }
384 
385     pub fn queue_mut(&mut self) -> &mut SigQueue {
386         &mut self.queue
387     }
388 
389     pub fn signal_mut(&mut self) -> &mut SigSet {
390         &mut self.signal
391     }
392     /// @brief 获取下一个要处理的信号(sig number越小的信号,优先级越高)
393     ///
394     /// @param pending 等待处理的信号
395     /// @param sig_mask 屏蔽了的信号
396     /// @return i32 下一个要处理的信号的number. 如果为0,则无效
397     pub fn next_signal(&self, sig_mask: &SigSet) -> Signal {
398         let mut sig = Signal::INVALID;
399 
400         let s = self.signal();
401         let m = *sig_mask;
402         m.is_empty();
403         // 获取第一个待处理的信号的号码
404         let x = s & (!m);
405         if x.bits() != 0 {
406             sig = Signal::from(ffz(x.complement().bits()) + 1);
407             return sig;
408         }
409 
410         // 暂时只支持64种信号
411         assert_eq!(MAX_SIG_NUM, 64);
412 
413         return sig;
414     }
415     /// @brief 收集信号的信息
416     ///
417     /// @param sig 要收集的信号的信息
418     /// @param pending 信号的排队等待标志
419     /// @return SigInfo 信号的信息
420     pub fn collect_signal(&mut self, sig: Signal) -> SigInfo {
421         let (info, still_pending) = self.queue_mut().find_and_delete(sig);
422 
423         // 如果没有仍在等待的信号,则清除pending位
424         if !still_pending {
425             self.signal_mut().remove(sig.into());
426         }
427 
428         if info.is_some() {
429             return info.unwrap();
430         } else {
431             // 信号不在sigqueue中,这意味着当前信号是来自快速路径,因此直接把siginfo设置为0即可。
432             let mut ret = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(Pid::from(0)));
433             ret.set_sig_type(SigType::Kill(Pid::new(0)));
434             return ret;
435         }
436     }
437 
438     /// @brief 从当前进程的sigpending中取出下一个待处理的signal,并返回给调用者。(调用者应当处理这个信号)
439     /// 请注意,进入本函数前,当前进程应当持有current_pcb().sighand.siglock
440     pub fn dequeue_signal(&mut self, sig_mask: &SigSet) -> (Signal, Option<SigInfo>) {
441         // kdebug!("dequeue signal");
442         // 获取下一个要处理的信号的编号
443         let sig = self.next_signal(sig_mask);
444 
445         let info: Option<SigInfo>;
446         if sig != Signal::INVALID {
447             // 如果下一个要处理的信号是合法的,则收集其siginfo
448             info = Some(self.collect_signal(sig));
449         } else {
450             info = None;
451         }
452 
453         // 当一个进程具有多个线程之后,在这里需要重新计算线程的flag中的TIF_SIGPENDING位
454         // recalc_sigpending();
455         return (sig, info);
456     }
457     /// @brief 从sigpending中删除mask中被置位的信号。也就是说,比如mask的第1位被置为1,那么就从sigqueue中删除所有signum为2的信号的信息。
458     pub fn flush_by_mask(&mut self, mask: &SigSet) {
459         // 定义过滤器,从sigqueue中删除mask中被置位的信号
460         let filter = |x: &SigInfo| !mask.contains(SigSet::from_bits_truncate(x.sig_no as u64));
461         self.queue.q.retain(filter);
462     }
463 }
464 
465 /// @brief 进程接收到的信号的队列
466 #[derive(Debug, Clone)]
467 pub struct SigQueue {
468     pub q: Vec<SigInfo>,
469 }
470 
471 #[allow(dead_code)]
472 impl SigQueue {
473     /// @brief 初始化一个新的信号队列
474     pub fn new(capacity: usize) -> Self {
475         SigQueue {
476             q: Vec::with_capacity(capacity),
477         }
478     }
479 
480     /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并返回它的引用
481     ///
482     /// @return (第一个满足要求的siginfo的引用; 是否有多个满足条件的siginfo)
483     pub fn find(&self, sig: Signal) -> (Option<&SigInfo>, bool) {
484         // 是否存在多个满足条件的siginfo
485         let mut still_pending = false;
486         let mut info: Option<&SigInfo> = None;
487 
488         for x in self.q.iter() {
489             if x.sig_no == sig as i32 {
490                 if info.is_some() {
491                     still_pending = true;
492                     break;
493                 } else {
494                     info = Some(x);
495                 }
496             }
497         }
498         return (info, still_pending);
499     }
500 
501     /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并将其从队列中删除,然后返回这个siginfo
502     ///
503     /// @return (第一个满足要求的siginfo; 从队列中删除前是否有多个满足条件的siginfo)
504     pub fn find_and_delete(&mut self, sig: Signal) -> (Option<SigInfo>, bool) {
505         // 是否存在多个满足条件的siginfo
506         let mut still_pending = false;
507         let mut first = true; // 标记变量,记录当前是否已经筛选出了一个元素
508 
509         let filter = |x: &mut SigInfo| {
510             if x.sig_no == sig as i32 {
511                 if !first {
512                     // 如果之前已经筛选出了一个元素,则不把当前元素删除
513                     still_pending = true;
514                     return false;
515                 } else {
516                     // 当前是第一个被筛选出来的元素
517                     first = false;
518                     return true;
519                 }
520             }
521             return false;
522         };
523         // 从sigqueue中过滤出结果
524         let mut filter_result: Vec<SigInfo> = self.q.extract_if(filter).collect();
525         // 筛选出的结果不能大于1个
526         assert!(filter_result.len() <= 1);
527 
528         return (filter_result.pop(), still_pending);
529     }
530 
531     /// @brief 从C的void*指针转换为static生命周期的可变引用
532     pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue {
533         let sq = p as *mut SigQueue;
534         let sq = unsafe { sq.as_mut::<'static>() }.unwrap();
535         return sq;
536     }
537 }
538 
539 impl Default for SigQueue {
540     fn default() -> Self {
541         Self {
542             q: Default::default(),
543         }
544     }
545 }
546 
547 ///
548 /// 定义了不同架构下实现 Signal 要实现的接口
549 ///
550 pub trait SignalArch {
551     /// 信号处理函数
552     ///
553     /// ## 参数
554     ///
555     /// - `frame` 中断栈帧
556     unsafe fn do_signal(frame: &mut TrapFrame);
557 
558     fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64;
559 }
560