xref: /DragonOS/kernel/src/ipc/signal_types.rs (revision dfe53cf087ef4c7b6db63d992906b062dc63e93f)
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],
72 }
73 
74 impl SignalStruct {
75     #[inline(never)]
76     pub fn new() -> Self {
77         Self {
78             inner: Box::<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],
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::Ignore));
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::Customized(_)));
133     }
134 }
135 
136 #[derive(Debug, Copy, Clone)]
137 #[allow(dead_code)]
138 pub enum SaHandlerType {
139     Error, // 暂时没有用上
140     Default,
141     Ignore,
142     Customized(VirtAddr),
143 }
144 
145 impl From<SaHandlerType> for usize {
146     fn from(value: SaHandlerType) -> Self {
147         match value {
148             SaHandlerType::Error => 2,
149             SaHandlerType::Ignore => 1,
150             SaHandlerType::Default => 0,
151             SaHandlerType::Customized(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::Default)
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::Ignore)
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::Error)
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::Default),
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::Default),
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::Ignore),
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, Default)]
357 pub struct SigPending {
358     signal: SigSet,
359     queue: SigQueue,
360 }
361 
362 impl SigPending {
363     /// 判断是否有待处理的信号
364     pub fn has_pending(&self) -> bool {
365         return !self.signal.is_empty();
366     }
367 
368     pub fn signal(&self) -> SigSet {
369         self.signal
370     }
371 
372     pub fn queue(&self) -> &SigQueue {
373         &self.queue
374     }
375 
376     pub fn queue_mut(&mut self) -> &mut SigQueue {
377         &mut self.queue
378     }
379 
380     pub fn signal_mut(&mut self) -> &mut SigSet {
381         &mut self.signal
382     }
383     /// @brief 获取下一个要处理的信号(sig number越小的信号,优先级越高)
384     ///
385     /// @param pending 等待处理的信号
386     /// @param sig_mask 屏蔽了的信号
387     /// @return i32 下一个要处理的信号的number. 如果为0,则无效
388     pub fn next_signal(&self, sig_mask: &SigSet) -> Signal {
389         let mut sig = Signal::INVALID;
390 
391         let s = self.signal();
392         let m = *sig_mask;
393         m.is_empty();
394         // 获取第一个待处理的信号的号码
395         let x = s & (!m);
396         if x.bits() != 0 {
397             sig = Signal::from(ffz(x.complement().bits()) + 1);
398             return sig;
399         }
400 
401         // 暂时只支持64种信号
402         assert_eq!(MAX_SIG_NUM, 64);
403 
404         return sig;
405     }
406     /// @brief 收集信号的信息
407     ///
408     /// @param sig 要收集的信号的信息
409     /// @param pending 信号的排队等待标志
410     /// @return SigInfo 信号的信息
411     pub fn collect_signal(&mut self, sig: Signal) -> SigInfo {
412         let (info, still_pending) = self.queue_mut().find_and_delete(sig);
413 
414         // 如果没有仍在等待的信号,则清除pending位
415         if !still_pending {
416             self.signal_mut().remove(sig.into());
417         }
418 
419         if let Some(info) = info {
420             return info;
421         } else {
422             // 信号不在sigqueue中,这意味着当前信号是来自快速路径,因此直接把siginfo设置为0即可。
423             let mut ret = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(Pid::from(0)));
424             ret.set_sig_type(SigType::Kill(Pid::new(0)));
425             return ret;
426         }
427     }
428 
429     /// @brief 从当前进程的sigpending中取出下一个待处理的signal,并返回给调用者。(调用者应当处理这个信号)
430     /// 请注意,进入本函数前,当前进程应当持有current_pcb().sighand.siglock
431     pub fn dequeue_signal(&mut self, sig_mask: &SigSet) -> (Signal, Option<SigInfo>) {
432         // kdebug!("dequeue signal");
433         // 获取下一个要处理的信号的编号
434         let sig = self.next_signal(sig_mask);
435 
436         let info: Option<SigInfo> = if sig != Signal::INVALID {
437             // 如果下一个要处理的信号是合法的,则收集其siginfo
438             Some(self.collect_signal(sig))
439         } else {
440             None
441         };
442 
443         // 当一个进程具有多个线程之后,在这里需要重新计算线程的flag中的TIF_SIGPENDING位
444         // recalc_sigpending();
445         return (sig, info);
446     }
447     /// @brief 从sigpending中删除mask中被置位的信号。也就是说,比如mask的第1位被置为1,那么就从sigqueue中删除所有signum为2的信号的信息。
448     pub fn flush_by_mask(&mut self, mask: &SigSet) {
449         // 定义过滤器,从sigqueue中删除mask中被置位的信号
450         let filter = |x: &SigInfo| !mask.contains(SigSet::from_bits_truncate(x.sig_no as u64));
451         self.queue.q.retain(filter);
452     }
453 }
454 
455 /// @brief 进程接收到的信号的队列
456 #[derive(Debug, Clone, Default)]
457 pub struct SigQueue {
458     pub q: Vec<SigInfo>,
459 }
460 
461 #[allow(dead_code)]
462 impl SigQueue {
463     /// @brief 初始化一个新的信号队列
464     pub fn new(capacity: usize) -> Self {
465         SigQueue {
466             q: Vec::with_capacity(capacity),
467         }
468     }
469 
470     /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并返回它的引用
471     ///
472     /// @return (第一个满足要求的siginfo的引用; 是否有多个满足条件的siginfo)
473     pub fn find(&self, sig: Signal) -> (Option<&SigInfo>, bool) {
474         // 是否存在多个满足条件的siginfo
475         let mut still_pending = false;
476         let mut info: Option<&SigInfo> = None;
477 
478         for x in self.q.iter() {
479             if x.sig_no == sig as i32 {
480                 if info.is_some() {
481                     still_pending = true;
482                     break;
483                 } else {
484                     info = Some(x);
485                 }
486             }
487         }
488         return (info, still_pending);
489     }
490 
491     /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并将其从队列中删除,然后返回这个siginfo
492     ///
493     /// @return (第一个满足要求的siginfo; 从队列中删除前是否有多个满足条件的siginfo)
494     pub fn find_and_delete(&mut self, sig: Signal) -> (Option<SigInfo>, bool) {
495         // 是否存在多个满足条件的siginfo
496         let mut still_pending = false;
497         let mut first = true; // 标记变量,记录当前是否已经筛选出了一个元素
498 
499         let filter = |x: &mut SigInfo| {
500             if x.sig_no == sig as i32 {
501                 if !first {
502                     // 如果之前已经筛选出了一个元素,则不把当前元素删除
503                     still_pending = true;
504                     return false;
505                 } else {
506                     // 当前是第一个被筛选出来的元素
507                     first = false;
508                     return true;
509                 }
510             }
511             return false;
512         };
513         // 从sigqueue中过滤出结果
514         let mut filter_result: Vec<SigInfo> = self.q.extract_if(filter).collect();
515         // 筛选出的结果不能大于1个
516         assert!(filter_result.len() <= 1);
517 
518         return (filter_result.pop(), still_pending);
519     }
520 
521     /// @brief 从C的void*指针转换为static生命周期的可变引用
522     pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue {
523         let sq = p as *mut SigQueue;
524         let sq = unsafe { sq.as_mut::<'static>() }.unwrap();
525         return sq;
526     }
527 }
528 
529 ///
530 /// 定义了不同架构下实现 Signal 要实现的接口
531 ///
532 pub trait SignalArch {
533     /// 信号处理函数
534     ///
535     /// ## 参数
536     ///
537     /// - `frame` 中断栈帧
538     unsafe fn do_signal(frame: &mut TrapFrame);
539 
540     fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64;
541 }
542