libc_core/signal.rs
1//! This module provides the `libc` types for Signal.
2//!
3//! MUSL: <https://github.com/bminor/musl/blob/c47ad25ea3b484e10326f933e927c0bc8cded3da/arch/powerpc/bits/signal.h>
4
5pub use crate::arch::{MContext, SignalStackFlags, UContext, UStack};
6use num_enum::TryFromPrimitive;
7
8/// POSIX 标准、线程扩展与实时信号枚举定义(信号编号从 1 开始)
9/// MUSL: <https://github.com/bminor/musl/blob/c47ad25ea3b484e10326f933e927c0bc8cded3da/arch/aarch64/bits/signal.h#L118>
10#[repr(u8)]
11#[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive)]
12pub enum SignalNum {
13 /// 终端挂起(Hangup)
14 HUP = 1,
15 /// 交互式中断(Interrupt)
16 INT,
17 /// 退出(Quit)
18 QUIT,
19 /// 非法指令(Illegal instruction)
20 ILL,
21 /// 断点(Trace/breakpoint trap)
22 TRAP,
23 /// 异常终止(Abort)
24 ABRT,
25 /// 总线错误(Bus error)
26 BUS,
27 /// 浮点异常(Floating-point exception)
28 FPE,
29 /// 强制终止(Kill,不可被捕获或忽略)
30 KILL,
31 /// 用户定义信号 1
32 USR1,
33 /// 段错误(Segmentation fault)
34 SEGV,
35 /// 用户定义信号 2
36 USR2,
37 /// 管道破裂(Broken pipe)
38 PIPE,
39 /// 报警时钟(Alarm clock)
40 ALRM,
41 /// 终止请求(Termination)
42 TERM,
43 /// 协处理器堆栈故障(栈浮点错误,仅部分平台支持)
44 STKFLT,
45 /// 子进程终止或状态变化(Child)
46 CHLD,
47 /// 继续执行(Continue)
48 CONT,
49 /// 停止进程(不可忽略)
50 STOP,
51 /// 终端停止(来自 TTY 的 Ctrl+Z)
52 TSTP,
53 /// 后台读取控制终端
54 TTIN,
55 /// 后台写入控制终端
56 TTOU,
57 /// 紧急条件(Urgent socket)
58 URG,
59 /// 超过 CPU 时间限制
60 XCPU,
61 /// 超过文件大小限制
62 XFSZ,
63 /// 虚拟计时器到期(Virtual alarm)
64 VTALRM,
65 /// 性能分析计时器到期(Profiling alarm)
66 PROF,
67 /// 窗口大小改变(Window size change)
68 WINCH,
69 /// 异步 I/O(I/O now possible)
70 IO,
71 /// 电源失败(Power failure)
72 PWR,
73 /// 非法系统调用(Bad syscall)
74 SYS,
75 /// POSIX 线程:定时器信号
76 TIMER,
77 /// POSIX 线程:取消信号
78 CANCEL,
79 /// POSIX 线程:同步调用信号
80 SYNCCALL,
81 /// 实时信号 3(Real-time signal 3)
82 RT3,
83 /// 实时信号 4
84 RT4,
85 /// 实时信号 5
86 RT5,
87 /// 实时信号 6
88 RT6,
89 /// 实时信号 7
90 RT7,
91 /// 实时信号 8
92 RT8,
93 /// 实时信号 9
94 RT9,
95 /// 实时信号 10
96 RT10,
97 /// 实时信号 11
98 RT11,
99 /// 实时信号 12
100 RT12,
101 /// 实时信号 13
102 RT13,
103 /// 实时信号 14
104 RT14,
105 /// 实时信号 15
106 RT15,
107 /// 实时信号 16
108 RT16,
109 /// 实时信号 17
110 RT17,
111 /// 实时信号 18
112 RT18,
113 /// 实时信号 19
114 RT19,
115 /// 实时信号 20
116 RT20,
117 /// 实时信号 21
118 RT21,
119 /// 实时信号 22
120 RT22,
121 /// 实时信号 23
122 RT23,
123 /// 实时信号 24
124 RT24,
125 /// 实时信号 25
126 RT25,
127 /// 实时信号 26
128 RT26,
129 /// 实时信号 27
130 RT27,
131 /// 实时信号 28
132 RT28,
133 /// 实时信号 29
134 RT29,
135 /// 实时信号 30
136 RT30,
137 /// 实时信号 31
138 RT31,
139 /// 最大实时信号(Real-time signal max)
140 RTMAX,
141}
142
143/// 实时信号(Real-time signals)的起始编号。
144pub const REAL_TIME_SIGNAL_NUM: usize = 33;
145
146impl SignalNum {
147 /// 从数字构造 `SignalNum` 枚举,如果超出合法范围则返回 `None`。
148 #[inline]
149 pub fn from_num(num: usize) -> Option<SignalNum> {
150 SignalNum::try_from(num as u8).ok()
151 }
152
153 /// 获取信号的编号(number)。
154 pub const fn num(&self) -> usize {
155 *self as usize
156 }
157
158 /// 判断是否为实时信号(Real-time Signal)。
159 ///
160 /// 实时信号从编号 [REAL_TIME_SIGNAL_NUM] 开始。
161 pub const fn is_rt(&self) -> bool {
162 *self as usize >= REAL_TIME_SIGNAL_NUM
163 }
164
165 /// 如果是实时信号,则返回其在实时信号表中的索引(从 1 开始)。
166 ///
167 /// 例如,编号为 [REAL_TIME_SIGNAL_NUM] 的信号返回 `1`。
168 #[inline]
169 pub fn real_time_index(&self) -> Option<usize> {
170 self.is_rt().then(|| self.num() - 32)
171 }
172
173 /// 获取信号的位掩码(bit mask)。
174 ///
175 /// 信号编号从 1 开始,因此返回值为 `1 << (num - 1)`。
176 pub const fn mask(&self) -> u64 {
177 bit!(self.num() - 1)
178 }
179}