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}