1 #![allow(non_camel_case_types)] 2 // 这是signal暴露给其他模块的公有的接口文件 3 4 use core::ffi::c_void; 5 use core::fmt::Debug; 6 7 use alloc::vec::Vec; 8 9 use crate::arch::fpu::FpState; 10 use crate::include::bindings::bindings::NULL; 11 // todo: 将这里更换为手动编写的ffi绑定 12 use crate::include::bindings::bindings::atomic_t; 13 use crate::include::bindings::bindings::pt_regs; 14 use crate::include::bindings::bindings::spinlock_t; 15 use crate::kerror; 16 use crate::libs::ffi_convert::FFIBind2Rust; 17 use crate::libs::ffi_convert::__convert_mut; 18 use crate::libs::ffi_convert::__convert_ref; 19 use crate::libs::refcount::RefCount; 20 21 /// 请注意,sigset_t这个bitmap, 第0位表示sig=1的信号。也就是说,SignalNumber-1才是sigset_t中对应的位 22 pub type sigset_t = u64; 23 /// 存储信号处理函数的地址(来自用户态) 24 pub type __signalfn_t = u64; 25 pub type __sighandler_t = __signalfn_t; 26 /// 存储信号处理恢复函数的地址(来自用户态) 27 pub type __sigrestorer_fn_t = u64; 28 pub type __sigrestorer_t = __sigrestorer_fn_t; 29 30 /// 最大的信号数量(改动这个值的时候请同步到signal.h) 31 pub const MAX_SIG_NUM: i32 = 64; 32 /// sigset所占用的u64的数量(改动这个值的时候请同步到signal.h) 33 pub const _NSIG_U64_CNT: i32 = MAX_SIG_NUM / 64; 34 /// 信号处理的栈的栈指针的最小对齐数量 35 pub const STACK_ALIGN: u64 = 16; 36 37 /// 由于signal_struct总是和sighand_struct一起使用,并且信号处理的过程中必定会对sighand加锁 38 /// 因此signal_struct不用加锁 39 /// **请将该结构体与`include/DragonOS/signal.h`中的保持同步** 40 #[repr(C)] 41 #[derive(Debug, Copy, Clone)] 42 pub struct signal_struct { 43 pub sig_cnt: atomic_t, 44 } 45 46 impl Default for signal_struct { 47 fn default() -> Self { 48 Self { 49 sig_cnt: Default::default(), 50 } 51 } 52 } 53 54 /** 55 * sigaction中的信号处理函数结构体 56 * 分为两种处理函数 57 */ 58 #[repr(C)] 59 #[derive(Copy, Clone)] 60 pub union sigaction__union_u { 61 pub _sa_handler: __sighandler_t, // 传统处理函数 62 pub _sa_sigaction: ::core::option::Option< 63 unsafe extern "C" fn( 64 sig: ::core::ffi::c_int, 65 sinfo: *mut siginfo, 66 arg1: *mut ::core::ffi::c_void, 67 ), 68 >, 69 } 70 71 impl core::fmt::Debug for sigaction__union_u { 72 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 73 f.write_str("sigaction__union_u") 74 } 75 } 76 77 impl Default for sigaction__union_u { 78 fn default() -> Self { 79 Self { 80 _sa_handler: NULL as u64, 81 } 82 } 83 } 84 85 // ============ sigaction结构体中的的sa_flags的可选值 begin =========== 86 pub const SA_FLAG_DFL: u64 = 1u64 << 0; // 当前sigaction表示系统默认的动作 87 pub const SA_FLAG_IGN: u64 = 1u64 << 1; // 当前sigaction表示忽略信号的动作 88 pub const SA_FLAG_RESTORER: u64 = 1u64 << 2; // 当前sigaction具有用户指定的restorer 89 pub const SA_FLAG_IMMUTABLE: u64 = 1u64 << 3; // 当前sigaction不可被更改 90 91 /// 所有的sa_flags的mask。(用于去除那些不存在的sa_flags位) 92 pub const SA_ALL_FLAGS: u64 = SA_FLAG_IGN | SA_FLAG_DFL | SA_FLAG_RESTORER | SA_FLAG_IMMUTABLE; 93 94 // ============ sigaction结构体中的的sa_flags的可选值 end =========== 95 96 /// 用户态程序传入的SIG_DFL的值 97 pub const USER_SIG_DFL: u64 = 0; 98 /// 用户态程序传入的SIG_IGN的值 99 pub const USER_SIG_IGN: u64 = 1; 100 101 /** 102 * @brief 信号处理结构体 103 */ 104 #[repr(C)] 105 #[derive(Debug, Copy, Clone)] 106 pub struct sigaction { 107 pub _u: sigaction__union_u, 108 pub sa_flags: u64, 109 pub sa_mask: sigset_t, // 为了可扩展性而设置的sa_mask 110 /// 信号处理函数执行结束后,将会跳转到这个函数内进行执行,然后执行sigreturn系统调用 111 pub sa_restorer: __sigrestorer_t, 112 } 113 114 impl Default for sigaction { 115 fn default() -> Self { 116 Self { 117 _u: Default::default(), 118 sa_flags: Default::default(), 119 sa_mask: Default::default(), 120 sa_restorer: Default::default(), 121 } 122 } 123 } 124 125 impl sigaction { 126 /// @brief 判断这个sigaction是否被忽略 127 pub fn ignored(&self, _sig: SignalNumber) -> bool { 128 if (self.sa_flags & SA_FLAG_IGN) != 0 { 129 return true; 130 } 131 // todo: 增加对sa_flags为SA_FLAG_DFL,但是默认处理函数为忽略的情况的判断 132 133 return false; 134 } 135 } 136 137 /// @brief 用户态传入的sigaction结构体(符合posix规范) 138 /// 请注意,我们会在sys_sigaction函数里面将其转换成内核使用的sigaction结构体 139 #[repr(C)] 140 #[derive(Debug)] 141 pub struct user_sigaction { 142 pub sa_handler: *mut core::ffi::c_void, 143 pub sa_sigaction: *mut core::ffi::c_void, 144 pub sa_mask: sigset_t, 145 pub sa_flags: u64, 146 pub sa_restorer: *mut core::ffi::c_void, 147 } 148 149 /** 150 * 信号消息的结构体,作为参数传入sigaction结构体中指向的处理函数 151 */ 152 #[repr(C)] 153 #[derive(Copy, Clone)] 154 pub struct siginfo { 155 pub _sinfo: __siginfo_union, 156 } 157 #[repr(C)] 158 #[derive(Copy, Clone)] 159 pub union __siginfo_union { 160 pub data: __siginfo_union_data, 161 pub padding: [u64; 4usize], 162 } 163 164 #[repr(C)] 165 #[derive(Copy, Clone)] 166 pub struct __siginfo_union_data { 167 pub si_signo: i32, 168 pub si_code: i32, 169 pub si_errno: i32, 170 pub reserved: u32, 171 pub _sifields: __sifields, 172 } 173 174 /** 175 * siginfo中,根据signal的来源不同,该union中对应了不同的数据./= 176 * 请注意,该union最大占用16字节 177 */ 178 #[repr(C)] 179 #[derive(Copy, Clone)] 180 pub union __sifields { 181 pub _kill: __sifields__kill, 182 } 183 184 /** 185 * 来自kill命令的signal 186 */ 187 #[repr(C)] 188 #[derive(Debug, Copy, Clone)] 189 pub struct __sifields__kill { 190 pub _pid: i64, /* 发起kill的进程的pid */ 191 } 192 193 impl siginfo { 194 pub fn new(sig: SignalNumber, _si_errno: i32, _si_code: si_code_val) -> Self { 195 siginfo { 196 _sinfo: __siginfo_union { 197 data: __siginfo_union_data { 198 si_signo: sig as i32, 199 si_code: _si_code as i32, 200 si_errno: _si_errno, 201 reserved: 0, 202 _sifields: super::signal_types::__sifields { 203 _kill: super::signal_types::__sifields__kill { _pid: 0 }, 204 }, 205 }, 206 }, 207 } 208 } 209 } 210 211 impl Debug for siginfo { 212 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 213 unsafe { 214 f.write_fmt(format_args!( 215 "si_signo:{}, si_code:{}, si_errno:{}, _pid:{}", 216 self._sinfo.data.si_signo, 217 self._sinfo.data.si_code, 218 self._sinfo.data.si_errno, 219 self._sinfo.data._sifields._kill._pid 220 )) 221 } 222 } 223 } 224 225 /** 226 * @brief 信号处理结构体,位于pcb之中 227 */ 228 #[repr(C)] 229 #[derive(Debug, Copy, Clone)] 230 pub struct sighand_struct { 231 pub siglock: spinlock_t, 232 pub count: RefCount, 233 pub action: [sigaction; MAX_SIG_NUM as usize], 234 } 235 236 impl Default for sighand_struct { 237 fn default() -> Self { 238 Self { 239 siglock: Default::default(), 240 count: Default::default(), 241 action: [Default::default(); MAX_SIG_NUM as usize], 242 } 243 } 244 } 245 246 /** 247 * @brief 正在等待的信号的标志位 248 */ 249 #[repr(C)] 250 #[derive(Debug, Copy, Clone)] 251 pub struct sigpending { 252 pub signal: sigset_t, 253 /// 信号队列 254 pub queue: *mut SigQueue, 255 } 256 257 /// siginfo中的si_code的可选值 258 /// 请注意,当这个值小于0时,表示siginfo来自用户态,否则来自内核态 259 #[allow(dead_code)] 260 #[repr(i32)] 261 pub enum si_code_val { 262 /// sent by kill, sigsend, raise 263 SI_USER = 0, 264 /// sent by kernel from somewhere 265 SI_KERNEL = 0x80, 266 /// 通过sigqueue发送 267 SI_QUEUE = -1, 268 /// 定时器过期时发送 269 SI_TIMER = -2, 270 /// 当实时消息队列的状态发生改变时发送 271 SI_MESGQ = -3, 272 /// 当异步IO完成时发送 273 SI_ASYNCIO = -4, 274 /// sent by queued SIGIO 275 SI_SIGIO = -5, 276 } 277 278 impl si_code_val { 279 /// 为si_code_val这个枚举类型实现从i32转换到枚举类型的转换函数 280 #[allow(dead_code)] 281 pub fn from_i32(x: i32) -> si_code_val { 282 match x { 283 0 => Self::SI_USER, 284 0x80 => Self::SI_KERNEL, 285 -1 => Self::SI_QUEUE, 286 -2 => Self::SI_TIMER, 287 -3 => Self::SI_MESGQ, 288 -4 => Self::SI_ASYNCIO, 289 -5 => Self::SI_SIGIO, 290 _ => panic!("si code not valid"), 291 } 292 } 293 } 294 295 #[allow(dead_code)] 296 #[derive(Debug, Clone, Copy)] 297 #[repr(i32)] 298 pub enum SignalNumber { 299 INVALID = 0, 300 SIGHUP = 1, 301 SIGINT, 302 SIGQUIT, 303 SIGILL, 304 SIGTRAP, 305 /// SIGABRT和SIGIOT共用这个号码 306 SIGABRT_OR_IOT, 307 SIGBUS, 308 SIGFPE, 309 SIGKILL, 310 SIGUSR1, 311 312 SIGSEGV = 11, 313 SIGUSR2, 314 SIGPIPE, 315 SIGALRM, 316 SIGTERM, 317 SIGSTKFLT, 318 SIGCHLD, 319 SIGCONT, 320 SIGSTOP, 321 SIGTSTP, 322 323 SIGTTIN = 21, 324 SIGTTOU, 325 SIGURG, 326 SIGXCPU, 327 SIGXFSZ, 328 SIGVTALRM, 329 SIGPROF, 330 SIGWINCH, 331 /// SIGIO和SIGPOLL共用这个号码 332 SIGIO_OR_POLL, 333 SIGPWR, 334 335 SIGSYS = 31, 336 } 337 338 /// 为SignalNumber实现判断相等的trait 339 impl PartialEq for SignalNumber { 340 fn eq(&self, other: &SignalNumber) -> bool { 341 *self as i32 == *other as i32 342 } 343 } 344 345 impl From<i32> for SignalNumber { 346 fn from(value: i32) -> Self { 347 if Self::valid_signal_number(value) { 348 let ret: SignalNumber = unsafe { core::mem::transmute(value) }; 349 return ret; 350 } else { 351 kerror!("Try to convert an invalid number to SignalNumber"); 352 return SignalNumber::INVALID; 353 } 354 } 355 } 356 impl SignalNumber { 357 /// 判断一个数字是否为可用的信号 358 fn valid_signal_number(x: i32) -> bool { 359 if x > 0 && x < MAX_SIG_NUM { 360 return true; 361 } else { 362 return false; 363 } 364 } 365 } 366 367 #[allow(dead_code)] 368 pub const SIGRTMIN: i32 = 32; 369 #[allow(dead_code)] 370 pub const SIGRTMAX: i32 = MAX_SIG_NUM; 371 372 /// @brief 将给定的signal_struct解析为Rust的signal.rs中定义的signal_struct的引用 373 /// 374 /// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的 375 impl FFIBind2Rust<crate::include::bindings::bindings::signal_struct> for signal_struct { 376 fn convert_mut( 377 src: *mut crate::include::bindings::bindings::signal_struct, 378 ) -> Option<&'static mut Self> { 379 return __convert_mut(src); 380 } 381 fn convert_ref( 382 src: *const crate::include::bindings::bindings::signal_struct, 383 ) -> Option<&'static Self> { 384 return __convert_ref(src); 385 } 386 } 387 388 /// @brief 将给定的siginfo解析为Rust的signal.rs中定义的siginfo的引用 389 /// 390 /// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的 391 impl FFIBind2Rust<crate::include::bindings::bindings::siginfo> for siginfo { 392 fn convert_mut( 393 src: *mut crate::include::bindings::bindings::siginfo, 394 ) -> Option<&'static mut Self> { 395 return __convert_mut(src); 396 } 397 fn convert_ref( 398 src: *const crate::include::bindings::bindings::siginfo, 399 ) -> Option<&'static Self> { 400 return __convert_ref(src); 401 } 402 } 403 404 /// @brief 将给定的sigset_t解析为Rust的signal.rs中定义的sigset_t的引用 405 /// 406 /// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的 407 impl FFIBind2Rust<crate::include::bindings::bindings::sigset_t> for sigset_t { 408 fn convert_mut( 409 src: *mut crate::include::bindings::bindings::sigset_t, 410 ) -> Option<&'static mut Self> { 411 return __convert_mut(src); 412 } 413 fn convert_ref( 414 src: *const crate::include::bindings::bindings::sigset_t, 415 ) -> Option<&'static Self> { 416 return __convert_ref(src); 417 } 418 } 419 420 /// @brief 将给定的sigpending解析为Rust的signal.rs中定义的sigpending的引用 421 /// 422 /// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的 423 impl FFIBind2Rust<crate::include::bindings::bindings::sigpending> for sigpending { 424 fn convert_mut( 425 src: *mut crate::include::bindings::bindings::sigpending, 426 ) -> Option<&'static mut Self> { 427 return __convert_mut(src); 428 } 429 fn convert_ref( 430 src: *const crate::include::bindings::bindings::sigpending, 431 ) -> Option<&'static Self> { 432 return __convert_ref(src); 433 } 434 } 435 436 /// @brief 将给定的来自bindgen的sighand_struct解析为Rust的signal.rs中定义的sighand_struct的引用 437 /// 438 /// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的,会导致无法自定义功能的问题。 439 impl FFIBind2Rust<crate::include::bindings::bindings::sighand_struct> for sighand_struct { 440 fn convert_mut( 441 src: *mut crate::include::bindings::bindings::sighand_struct, 442 ) -> Option<&'static mut Self> { 443 return __convert_mut(src); 444 } 445 fn convert_ref( 446 src: *const crate::include::bindings::bindings::sighand_struct, 447 ) -> Option<&'static Self> { 448 return __convert_ref(src); 449 } 450 } 451 452 /// @brief 将给定的来自bindgen的sigaction解析为Rust的signal.rs中定义的sigaction的引用 453 impl FFIBind2Rust<crate::include::bindings::bindings::sigaction> for sigaction { 454 fn convert_mut( 455 src: *mut crate::include::bindings::bindings::sigaction, 456 ) -> Option<&'static mut Self> { 457 return __convert_mut(src); 458 } 459 fn convert_ref( 460 src: *const crate::include::bindings::bindings::sigaction, 461 ) -> Option<&'static Self> { 462 return __convert_ref(src); 463 } 464 } 465 466 /// @brief 进程接收到的信号的队列 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: SignalNumber) -> (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 unsafe { x._sinfo.data.si_signo } == 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: SignalNumber) -> (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 unsafe { x._sinfo.data.si_signo } == 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 } else { 521 return false; 522 } 523 }; 524 // 从sigqueue中过滤出结果 525 let mut filter_result: Vec<siginfo> = self.q.drain_filter(filter).collect(); 526 // 筛选出的结果不能大于1个 527 assert!(filter_result.len() <= 1); 528 529 return (filter_result.pop(), still_pending); 530 } 531 532 /// @brief 从sigqueue中删除mask中被置位的信号。也就是说,比如mask的第1位被置为1,那么就从sigqueue中删除所有signum为2的信号的信息。 533 pub fn flush_by_mask(&mut self, mask: &sigset_t) { 534 // 定义过滤器,从sigqueue中删除mask中被置位的信号 535 let filter = |x: &mut siginfo| { 536 if sig_is_member(mask, SignalNumber::from(unsafe { x._sinfo.data.si_signo })) { 537 true 538 } else { 539 false 540 } 541 }; 542 let filter_result: Vec<siginfo> = self.q.drain_filter(filter).collect(); 543 // 回收这些siginfo 544 for x in filter_result { 545 drop(x) 546 } 547 } 548 549 /// @brief 从C的void*指针转换为static生命周期的可变引用 550 pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue { 551 let sq = p as *mut SigQueue; 552 let sq = unsafe { sq.as_mut::<'static>() }.unwrap(); 553 return sq; 554 } 555 } 556 557 impl Default for SigQueue { 558 fn default() -> Self { 559 Self { 560 q: Default::default(), 561 } 562 } 563 } 564 565 /// @brief 清除sigset中,某个信号对应的标志位 566 #[inline] 567 pub fn sigset_del(set: &mut sigset_t, sig: SignalNumber) { 568 let sig = sig as i32 - 1; 569 if _NSIG_U64_CNT == 1 { 570 *set &= !(1 << sig); 571 } else { 572 // 暂时不支持超过64个信号 573 panic!("Unsupported signal number: {:?}", sig); 574 } 575 } 576 577 /// @brief 将指定的信号在sigset中的对应bit进行置位 578 #[inline] 579 pub fn sigset_add(set: &mut sigset_t, sig: SignalNumber) { 580 *set |= 1 << ((sig as u32) - 1); 581 } 582 583 /// @brief 将sigset清零 584 #[inline] 585 pub fn sigset_clear(set: &mut sigset_t) { 586 *set = 0; 587 } 588 589 /// @brief 将mask中置为1的位,在sigset中清零 590 #[inline] 591 pub fn sigset_delmask(set: &mut sigset_t, mask: u64) { 592 *set &= !mask; 593 } 594 595 /// @brief 判断两个sigset是否相等 596 #[inline] 597 pub fn sigset_equal(a: &sigset_t, b: &sigset_t) -> bool { 598 if _NSIG_U64_CNT == 1 { 599 return *a == *b; 600 } 601 return false; 602 } 603 604 /// @brief 使用指定的值,初始化sigset(为支持将来超过64个signal留下接口) 605 #[inline] 606 pub fn sigset_init(new_set: &mut sigset_t, mask: u64) { 607 *new_set = mask; 608 match _NSIG_U64_CNT { 609 1 => {} 610 _ => { 611 // 暂时不支持大于64个信号 612 todo!(); 613 } 614 }; 615 } 616 617 /// @brief 判断指定的信号在sigset中的对应位是否被置位 618 /// @return true: 给定的信号在sigset中被置位 619 /// @return false: 给定的信号在sigset中没有被置位 620 #[inline] 621 pub fn sig_is_member(set: &sigset_t, _sig: SignalNumber) -> bool { 622 return if 1 & (set >> ((_sig as u32) - 1)) != 0 { 623 true 624 } else { 625 false 626 }; 627 } 628 629 #[repr(C)] 630 #[derive(Debug, Clone, Copy)] 631 pub struct sigframe { 632 /// 指向restorer的地址的指针。(该变量必须放在sigframe的第一位,因为这样才能在handler返回的时候,跳转到对应的代码,执行sigreturn) 633 pub ret_code_ptr: *mut core::ffi::c_void, 634 /// signum 635 pub arg0: u64, 636 /// siginfo pointer 637 pub arg1: usize, 638 /// sigcontext pointer 639 pub arg2: usize, 640 641 pub handler: *mut c_void, 642 pub info: siginfo, 643 pub context: sigcontext, 644 } 645 646 #[derive(Debug, Clone, Copy)] 647 pub struct sigcontext { 648 /// sigcontext的标志位 649 pub sc_flags: u64, 650 pub sc_stack: signal_stack, // 信号处理程序备用栈信息 651 652 pub regs: pt_regs, // 暂存的系统调用/中断返回时,原本要弹出的内核栈帧 653 pub trap_num: u64, // 用来保存线程结构体中的trap_num字段 654 pub oldmask: u64, // 暂存的执行信号处理函数之前的,被设置block的信号 655 pub cr2: u64, // 用来保存线程结构体中的cr2字段 656 pub err_code: u64, // 用来保存线程结构体中的err_code字段 657 // todo: 支持x87浮点处理器后,在这里增加浮点处理器的状态结构体指针 658 pub reserved_for_x87_state: u64, 659 pub reserved: [u64; 8], 660 } 661 662 /// @brief 信号处理备用栈的信息 663 #[derive(Debug, Clone, Copy)] 664 pub struct signal_stack { 665 pub sp: *mut c_void, 666 pub flags: u32, 667 pub size: u32, 668 pub fpstate: FpState, 669 } 670