os/uapi/
signal.rs

1//! 信号处理行为标志和相关常量定义
2//!
3//! 这些常量用于信号处理函数的行为控制,
4//! 以及信号屏蔽操作等。
5
6use core::{
7    ffi::{c_char, c_int, c_long, c_uint, c_ulong, c_ulonglong, c_void},
8    fmt::Debug,
9};
10
11use bitflags::bitflags;
12
13use crate::{
14    arch::trap::TrapFrame,
15    uapi::types::{ClockT, PidT, SigSetT, SizeT, UidT},
16};
17
18/// 信号集合的大小(以字节为单位)
19pub const SIGSET_SIZE: usize = core::mem::size_of::<SigSetT>();
20
21#[repr(C)]
22#[derive(Clone, Copy)]
23pub union __SaHandler {
24    /// C: `void (*sa_handler)(int)`
25    /// 用于 SA_SIGINFO 未设置时的普通处理器 (单参数)。
26    pub sa_handler: SaHandlerPtr,
27
28    /// C: `void (*sa_sigaction)(int, siginfo_t *, void *)`
29    /// 用于 SA_SIGINFO 设置时的实时信号处理器 (三参数)。
30    pub sa_sigaction: SaSigactionPtr,
31}
32
33impl Debug for __SaHandler {
34    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35        write!(f, "__SaHandler {{ ... }}")
36    }
37}
38
39#[repr(C)]
40#[derive(Clone, Copy, Debug)]
41/// Linux/POSIX 信号处理动作结构体 (struct sigaction)
42pub struct SignalAction {
43    /// C: `union { ... } __sa_handler`
44    /// 包含单参数或三参数信号处理函数指针。
45    pub __sa_handler: __SaHandler,
46
47    /// C: `sigset_t sa_mask`
48    /// 信号屏蔽字,在执行处理函数时将被自动添加到线程的阻塞集中。
49    pub sa_mask: SigSetT,
50
51    /// C: `int sa_flags`
52    /// 信号处理行为标志 (如 SA_SIGINFO, SA_RESETHAND)。
53    /// 注意:这里使用 i32 或 c_int 更符合 C 的 int 类型。
54    pub sa_flags: c_int,
55    /// C: `void (*sa_restorer)(void)`
56    /// 信号恢复函数指针。通常由 C 库设置,用于从信号处理器返回。
57    pub sa_restorer: SaRestorerPtr,
58}
59
60impl SignalAction {
61    /// 获取单参数信号处理器。
62    /// 这是一个不安全操作,因为它访问联合体字段。
63    pub unsafe fn sa_handler(&self) -> SaHandlerPtr {
64        unsafe { self.__sa_handler.sa_handler }
65    }
66
67    /// 获取三参数信号处理器。
68    /// 这是一个不安全操作,因为它访问联合体字段。
69    pub unsafe fn sa_sigaction(&self) -> SaSigactionPtr {
70        unsafe { self.__sa_handler.sa_sigaction }
71    }
72
73    /// 安全地检查是否设置了 SA_SIGINFO 标志。
74    pub fn is_siginfo(&self) -> bool {
75        // 假设您的 SaFlags 已经正确转换并可以使用
76        (self.sa_flags as u32) & SaFlags::SIGINFO.bits() != 0
77    }
78
79    /// 创建一个新的 SignalAction 实例。
80    /// # 参数:
81    /// * `handler`: 信号处理函数指针 (单参数)
82    /// * `flags`: 信号处理行为标志
83    /// * `mask`: 信号屏蔽字
84    /// # 返回值:新的 SignalAction 实例
85    pub fn new(handler: SaHandlerPtr, flags: SaFlags, mask: SignalFlags) -> Self {
86        Self {
87            __sa_handler: __SaHandler {
88                sa_handler: handler,
89            },
90            sa_mask: mask.bits() as SigSetT,
91            sa_flags: flags.bits() as c_int,
92            sa_restorer: core::ptr::null_mut(),
93        }
94    }
95}
96
97impl Default for SignalAction {
98    /// 创建一个默认的 SignalAction 实例,使用 SIG_DFL 作为处理器,空标志和空屏蔽字。
99    fn default() -> Self {
100        Self::new(SIG_DFL as *mut _, SaFlags::empty(), SignalFlags::empty())
101    }
102}
103
104/* 信号定义 */
105pub const NSIG: usize = 31;
106
107pub const NUM_SIGHUP: usize = 1;
108pub const NUM_SIGINT: usize = 2;
109pub const NUM_SIGQUIT: usize = 3;
110pub const NUM_SIGILL: usize = 4;
111pub const NUM_SIGTRAP: usize = 5;
112pub const NUM_SIGABRT: usize = 6;
113pub const NUM_SIGBUS: usize = 7;
114pub const NUM_SIGFPE: usize = 8;
115pub const NUM_SIGKILL: usize = 9;
116pub const NUM_SIGUSR1: usize = 10;
117pub const NUM_SIGSEGV: usize = 11;
118pub const NUM_SIGUSR2: usize = 12;
119pub const NUM_SIGPIPE: usize = 13;
120pub const NUM_SIGALRM: usize = 14;
121pub const NUM_SIGTERM: usize = 15;
122pub const NUM_SIGSTKFLT: usize = 16;
123pub const NUM_SIGCHLD: usize = 17;
124pub const NUM_SIGCONT: usize = 18;
125pub const NUM_SIGSTOP: usize = 19;
126pub const NUM_SIGTSTP: usize = 20;
127pub const NUM_SIGTTIN: usize = 21;
128pub const NUM_SIGTTOU: usize = 22;
129pub const NUM_SIGURG: usize = 23;
130pub const NUM_SIGXCPU: usize = 24;
131pub const NUM_SIGXFSZ: usize = 25;
132pub const NUM_SIGVTALRM: usize = 26;
133pub const NUM_SIGPROF: usize = 27;
134pub const NUM_SIGWINCH: usize = 28;
135pub const NUM_SIGIO: usize = 29;
136pub const NUM_SIGPWR: usize = 30;
137pub const NUM_SIGSYS: usize = 31;
138
139bitflags! {
140    #[derive(Clone, Debug, Copy)]
141    #[repr(transparent)]
142    /// 信号标志位,用于表示信号集合。
143    pub struct SignalFlags: usize {
144        const SIGHUP = 1 << (NUM_SIGHUP - 1);
145        const SIGINT = 1 << (NUM_SIGINT - 1);
146        const SIGQUIT = 1 << (NUM_SIGQUIT - 1);
147        const SIGILL = 1 << (NUM_SIGILL - 1);
148        const SIGTRAP = 1 << (NUM_SIGTRAP - 1);
149        const SIGABRT = 1 << (NUM_SIGABRT - 1);
150        const SIGBUS = 1 << (NUM_SIGBUS - 1);
151        const SIGFPE = 1 << (NUM_SIGFPE - 1);
152        const SIGKILL = 1 << (NUM_SIGKILL - 1);
153        const SIGUSR1 = 1 << (NUM_SIGUSR1 - 1);
154        const SIGSEGV = 1 << (NUM_SIGSEGV - 1);
155        const SIGUSR2 = 1 << (NUM_SIGUSR2 - 1);
156        const SIGPIPE = 1 << (NUM_SIGPIPE - 1);
157        const SIGALRM = 1 << (NUM_SIGALRM - 1);
158        const SIGTERM = 1 << (NUM_SIGTERM - 1);
159        const SIGSTKFLT = 1 << (NUM_SIGSTKFLT - 1);
160        const SIGCHLD = 1 << (NUM_SIGCHLD - 1);
161        const SIGCONT = 1 << (NUM_SIGCONT - 1);
162        const SIGSTOP = 1 << (NUM_SIGSTOP - 1);
163        const SIGTSTP = 1 << (NUM_SIGTSTP - 1);
164        const SIGTTIN = 1 << (NUM_SIGTTIN - 1);
165        const SIGTTOU = 1 << (NUM_SIGTTOU - 1);
166        const SIGURG = 1 << (NUM_SIGURG - 1);
167        const SIGXCPU = 1 << (NUM_SIGXCPU - 1);
168        const SIGXFSZ = 1 << (NUM_SIGXFSZ - 1);
169        const SIGVTALRM = 1 << (NUM_SIGVTALRM - 1);
170        const SIGPROF = 1 << (NUM_SIGPROF - 1);
171        const SIGWINCH = 1 << (NUM_SIGWINCH - 1);
172        const SIGIO = 1 << (NUM_SIGIO - 1);
173        const SIGPWR = 1 << (NUM_SIGPWR - 1);
174        const SIGSYS = 1 << (NUM_SIGSYS - 1);
175    }
176}
177
178impl SignalFlags {
179    pub fn from_signal_num(sig_num: usize) -> Option<Self> {
180        if sig_num == 0 || sig_num > NSIG {
181            return None;
182        }
183        Some(SignalFlags::from_bits(1 << (sig_num - 1)).unwrap())
184    }
185
186    /// 将 SignalFlags 转换为对应的信号编号 (1-NSIG)。
187    /// 如果包含多个信号,则返回第一个匹配的信号编号。
188    /// 如果不包含任何信号,则返回 0 表示无效。
189    pub fn to_signal_number(&self) -> usize {
190        for sig_num in 1..=NSIG {
191            if self.contains(SignalFlags::from_bits(1 << (sig_num - 1)).unwrap()) {
192                return sig_num;
193            }
194        }
195        0 // 如果没有匹配的信号,返回 0 表示无效
196    }
197
198    pub fn from_sigset_t(set: SigSetT) -> Self {
199        SignalFlags::from_bits(set as usize).unwrap()
200    }
201
202    pub fn to_sigset_t(&self) -> SigSetT {
203        self.bits() as SigSetT
204    }
205}
206
207// --- 信号处理函数类型定义 ---
208// C 兼容的函数指针类型
209pub type SaHandlerFn = extern "C" fn(c_int);
210pub type SaSigactionFn = extern "C" fn(c_int, *const SigInfoT, *mut c_void);
211pub type SaRestorerFn = extern "C" fn();
212
213// 指针别名,用于存储 SIG_DFL (0) 和 SIG_IGN (1)
214pub type SaHandlerPtr = *mut SaHandlerFn;
215pub type SaSigactionPtr = *mut SaSigactionFn;
216pub type SaRestorerPtr = *mut SaRestorerFn;
217
218// --- 信号处理行为标志 (SA_FLAGS) ---
219// 用于 struct sigaction 的 sa_flags 字段,控制信号处理函数的行为。
220bitflags! {
221    /// 信号处理行为标志,用于 sigaction 系统调用。
222    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
223    #[repr(transparent)]
224    pub struct SaFlags: u32 {
225        /// 阻止 SIGCHLD 在子进程停止时生成。
226        const NOCLDSTOP = 0x0000_0001;
227
228        /// 在 SIGCHLD 上设置,以禁止僵尸进程 (子进程退出时不产生僵尸进程)。
229        const NOCLDWAIT = 0x0000_0002;
230
231        /// 使用 siginfo_t 结构体传递信号详细信息 (开启实时信号行为,使用三参数处理器)。
232        const SIGINFO = 0x0000_0004;
233
234        /// 表示将使用已注册的备用信号栈 (sigaltstack)。
235        const ONSTACK = 0x0800_0000;
236
237        /// 标志,使得被中断的慢速系统调用在信号处理函数返回后自动重新启动。
238        const RESTART = 0x1000_0000;
239
240        /// 防止当前信号在处理函数执行期间被自动阻塞 (即,不自动添加到屏蔽字)。
241        const NODEFER = 0x4000_0000;
242
243        /// 清除信号处理函数:信号在投递后,其处理函数被重置为 SIG_DFL。
244        const RESETHAND = 0x8000_0000;
245
246        /// 不受支持的标志位。用于用户空间检测内核对标志位的支持情况。
247        const UNSUPPORTED = 0x0000_0400;
248
249        /// 暴露架构定义的标签位(tag bits)到 siginfo.si_addr 中。
250        const EXPOSE_TAGBITS = 0x0000_0800;
251
252        // --- 历史名称别名 ---
253        /// 历史上的 SA_NOMASK 名称,等同于 SA_NODEFER。
254        const NOMASK = Self::NODEFER.bits();
255
256        /// 历史上的 SA_ONESHOT 名称,等同于 SA_RESETHAND.
257        const ONESHOT = Self::RESETHAND.bits();
258    }
259}
260
261const ALL_KNOWN_FLAGS: SaFlags = SaFlags::all();
262
263const NOW_SUPPORTED_FLAGS: SaFlags = SaFlags::UNSUPPORTED;
264
265impl SaFlags {
266    /// 检查标志位是否在当前内核支持的范围内
267    pub fn is_supported(&self) -> bool {
268        self.bits() & !NOW_SUPPORTED_FLAGS.bits() == 0
269    }
270
271    /// 检查标志位是否在已知标志范围内
272    pub fn is_known(&self) -> bool {
273        self.bits() & !ALL_KNOWN_FLAGS.bits() == 0
274    }
275}
276
277// --- 信号屏蔽操作常量 (sigprocmask / rt_sigprocmask) ---
278// 用于 sigprocmask 函数的 how 参数,指示如何修改信号屏蔽字。
279
280/// 将信号集添加到当前的屏蔽字中(阻塞信号)。
281pub const SIG_BLOCK: i32 = 0;
282
283/// 从当前的屏蔽字中移除信号集(解除阻塞)。
284pub const SIG_UNBLOCK: i32 = 1;
285
286/// 将当前的屏蔽字设置为给定的信号集。
287pub const SIG_SETMASK: i32 = 2;
288
289// --- 信号处理函数特殊值 ---
290
291// 这里的处理动作值(SIG_DFL, SIG_IGN, SIG_ERR)在 C 语言中是特殊的指针值,
292// 在 Rust 中,我们使用 isize 来模拟这些与指针相关的常量。
293
294/// 默认信号处理:由内核执行默认动作 (终止、停止、忽略等)。
295pub const SIG_DFL: isize = 0;
296
297/// 忽略信号:内核将忽略该信号。
298pub const SIG_IGN: isize = 1;
299
300/// 错误返回值:表示信号系统调用的错误。
301pub const SIG_ERR: isize = -1;
302
303#[repr(C)]
304#[derive(Clone, Copy)]
305/// 信号详细信息结构体 (siginfo_t)
306pub struct SigInfoT {
307    // --- 头部字段 (条件编译省略) ---
308    // 这是大多数现代系统的默认顺序
309    pub si_signo: c_int,
310    pub si_errno: c_int,
311    pub si_code: c_int,
312
313    // --- 联合体字段 ---
314    pub __si_fields: __SiFields,
315}
316
317impl SigInfoT {
318    /// 创建一个新的、空的 SigInfoT 实例,所有字段初始化为零。
319    pub fn new() -> Self {
320        Self {
321            si_signo: 0,
322            si_errno: 0,
323            si_code: 0,
324            __si_fields: __SiFields {
325                __pad: [0; __SIGINFO_PAD_SIZE],
326            },
327        }
328    }
329}
330
331#[repr(C)]
332#[derive(Clone, Copy)]
333pub union Sigval {
334    pub sival_int: c_int,
335    pub sival_ptr: *mut c_void,
336}
337
338const __SIGINFO_PAD_SIZE: usize =
339    128 - 2 * core::mem::size_of::<c_int>() - core::mem::size_of::<c_long>();
340
341#[repr(C)]
342#[derive(Clone, Copy)]
343pub union __SiFields {
344    // char __pad[128 - 2*sizeof(int) - sizeof(long)];
345    pub __pad: [c_char; __SIGINFO_PAD_SIZE], // 使用计算出的填充数组
346
347    pub __si_common: __SiCommon,
348    pub __sigfault: __SigFault,
349    pub __sigpoll: __SigPoll,
350    pub __sigsys: __SigSys,
351}
352
353#[repr(C)]
354#[derive(Clone, Copy)]
355pub struct __SiCommon {
356    pub __first: __FirstCommon,
357    pub __second: __SecondCommon,
358}
359
360#[repr(C)]
361#[derive(Clone, Copy)]
362pub struct __SigFault {
363    pub si_addr: *mut c_void,
364    pub si_addr_lsb: i16, // short
365    pub __first: __FirstFault,
366}
367
368#[repr(C)]
369#[derive(Clone, Copy)]
370pub struct __SigPoll {
371    pub si_band: c_long, // long
372    pub si_fd: c_int,
373}
374
375#[repr(C)]
376#[derive(Clone, Copy)]
377pub struct __SigSys {
378    pub si_call_addr: *mut c_void,
379    pub si_syscall: c_int,
380    pub si_arch: c_uint, // unsigned
381}
382
383// --- 内部联合体和结构体定义 (自内向外) ---
384
385#[repr(C)]
386#[derive(Clone, Copy)]
387pub union __FirstCommon {
388    pub __piduid: __PidUid,
389    pub __timer: __Timer,
390}
391
392#[repr(C)]
393#[derive(Clone, Copy)]
394pub struct __PidUid {
395    pub si_pid: PidT,
396    pub si_uid: UidT,
397}
398
399#[repr(C)]
400#[derive(Clone, Copy)]
401pub struct __Timer {
402    pub si_timerid: c_int,
403    pub si_overrun: c_int,
404}
405
406#[repr(C)]
407#[derive(Clone, Copy)]
408pub union __SecondCommon {
409    pub si_value: Sigval,
410    pub __sigchld: __SigChld,
411}
412
413#[repr(C)]
414#[derive(Clone, Copy)]
415pub struct __SigChld {
416    pub si_status: c_int,
417    pub si_utime: ClockT,
418    pub si_stime: ClockT,
419}
420
421#[repr(C)]
422#[derive(Clone, Copy)]
423pub union __FirstFault {
424    pub __addr_bnd: __AddrBnd,
425    pub si_pkey: c_uint, // unsigned si_pkey
426}
427
428#[repr(C)]
429#[derive(Clone, Copy)]
430pub struct __AddrBnd {
431    pub si_lower: *mut c_void,
432    pub si_upper: *mut c_void,
433}
434
435/// 用户态信号处理上下文结构体
436/// 该结构体包含恢复进程执行所需的所有状态。
437#[repr(C)]
438#[derive(Clone, Copy, Debug)]
439pub struct UContextT {
440    /// 标志位
441    pub uc_flags: c_ulong,
442    /// 链接到下一个上下文
443    pub uc_link: *mut UContextT,
444    /// 信号栈信息
445    pub uc_stack: SignalStack,
446    /// 信号掩码
447    pub uc_sigmask: SigSetT,
448    /// 机器上下文
449    pub uc_mcontext: MContextT,
450}
451
452impl UContextT {
453    /// 创建一个新的 UContextT 实例,所有字段初始化为零或默认值。
454    pub fn default() -> Self {
455        Self {
456            uc_flags: 0,
457            uc_link: core::ptr::null_mut(),
458            uc_stack: SignalStack::default(),
459            uc_sigmask: 0,
460            uc_mcontext: MContextT::new(),
461        }
462    }
463
464    /// 创建一个新的 UContextT 实例,使用指定的字段值。
465    /// # 参数:
466    /// * `flags`: 上下文标志
467    /// * `link`: 指向下一个上下文的指针
468    /// * `stack`: 信号栈信息
469    /// * `sigmask`: 信号掩码
470    /// * `mcontext`: 机器上下文
471    /// # 返回值: 新的 UContextT 实例
472    pub fn new(
473        flags: c_ulong,
474        link: *mut UContextT,
475        stack: SignalStack,
476        sigmask: SigSetT,
477        mcontext: MContextT,
478    ) -> Self {
479        Self {
480            uc_flags: flags,
481            uc_link: link,
482            uc_stack: stack,
483            uc_sigmask: sigmask,
484            uc_mcontext: mcontext,
485        }
486    }
487}
488
489/// 信号栈信息结构体
490/// 该结构体用于描述备用信号栈的信息。
491#[repr(C)]
492#[derive(Clone, Copy, Debug, Default)]
493pub struct SignalStack {
494    /// 栈顶地址, 对应 C 中的 void *ss_sp
495    pub ss_sp: usize,
496    /// 栈状态标志
497    pub ss_flags: c_int,
498    /// 栈大小
499    pub ss_size: SizeT,
500}
501
502/// 最小信号栈大小
503pub const MINSIGSTKSZ: usize = 2048;
504/// 默认信号栈大小
505pub const SIGSTKSZ: usize = 8192;
506// 信号栈标志位
507/// 信号栈正在使用中
508pub const SS_ONSTACK: usize = 1;
509/// 信号栈被禁用
510pub const SS_DISABLE: usize = 2;
511/// 自动解除信号栈
512pub const SS_AUTODISARM: usize = 1 << 31;
513/// 信号栈标志位掩码
514pub const SS_FLAG_BITS: usize = SS_AUTODISARM;
515
516#[repr(C)]
517#[derive(Clone, Copy, Debug)]
518/// 机器上下文结构体
519pub struct MContextT {
520    /// 通用寄存器数组
521    pub gregs: [c_ulong; 32],
522    /// 浮点寄存器数组
523    /// XXX: 实际并未使用浮点寄存器
524    ///      且注意struct pending?
525    pub fpregs: [c_ulonglong; 66],
526}
527
528impl MContextT {
529    /// 创建一个新的 MContextT 实例,所有寄存器初始化为零。
530    pub fn new() -> Self {
531        Self {
532            gregs: [0; 32],
533            fpregs: [0; 66],
534        }
535    }
536
537    /// 从 TrapFrame 创建 MContextT 实例
538    pub fn from_trap_frame(tf: &TrapFrame) -> Self {
539        tf.to_mcontext()
540    }
541}
542
543/// uc_mcontext_ext has valid high gprs
544pub const UC_GPRS_HIGH: usize = 1;
545/// uc_mcontext_ext has valid vector regs
546pub const UC_VXRS: usize = 2;