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