1 use core::{ 2 ffi::c_void, 3 mem::size_of, 4 ops::{Deref, DerefMut}, 5 sync::atomic::AtomicI64, 6 }; 7 8 use alloc::{boxed::Box, vec::Vec}; 9 use system_error::SystemError; 10 11 use crate::{ 12 arch::{ 13 asm::bitops::ffz, 14 interrupt::TrapFrame, 15 ipc::signal::{SigCode, SigFlags, SigSet, Signal, MAX_SIG_NUM}, 16 }, 17 mm::VirtAddr, 18 process::Pid, 19 syscall::user_access::UserBufferWriter, 20 }; 21 22 /// 用户态程序传入的SIG_DFL的值 23 pub const USER_SIG_DFL: u64 = 0; 24 /// 用户态程序传入的SIG_IGN的值 25 pub const USER_SIG_IGN: u64 = 1; 26 /// 用户态程序传入的SIG_ERR的值 27 pub const USER_SIG_ERR: u64 = 2; 28 29 // 因为 Rust 编译器不能在常量声明中正确识别级联的 "|" 运算符(experimental feature: https://github.com/rust-lang/rust/issues/67792),因此 30 // 暂时只能通过这种方法来声明这些常量,这些常量暂时没有全部用到,但是都出现在 linux 的判断逻辑中,所以都保留下来了 31 #[allow(dead_code)] 32 pub const SIG_KERNEL_ONLY_MASK: SigSet = 33 Signal::into_sigset(Signal::SIGSTOP).union(Signal::into_sigset(Signal::SIGKILL)); 34 35 pub const SIG_KERNEL_STOP_MASK: SigSet = Signal::into_sigset(Signal::SIGSTOP) 36 .union(Signal::into_sigset(Signal::SIGTSTP)) 37 .union(Signal::into_sigset(Signal::SIGTTIN)) 38 .union(Signal::into_sigset(Signal::SIGTTOU)); 39 #[allow(dead_code)] 40 pub const SIG_KERNEL_COREDUMP_MASK: SigSet = Signal::into_sigset(Signal::SIGQUIT) 41 .union(Signal::into_sigset(Signal::SIGILL)) 42 .union(Signal::into_sigset(Signal::SIGTRAP)) 43 .union(Signal::into_sigset(Signal::SIGABRT_OR_IOT)) 44 .union(Signal::into_sigset(Signal::SIGFPE)) 45 .union(Signal::into_sigset(Signal::SIGSEGV)) 46 .union(Signal::into_sigset(Signal::SIGBUS)) 47 .union(Signal::into_sigset(Signal::SIGSYS)) 48 .union(Signal::into_sigset(Signal::SIGXCPU)) 49 .union(Signal::into_sigset(Signal::SIGXFSZ)); 50 #[allow(dead_code)] 51 pub const SIG_KERNEL_IGNORE_MASK: SigSet = Signal::into_sigset(Signal::SIGCONT) 52 .union(Signal::into_sigset(Signal::SIGFPE)) 53 .union(Signal::into_sigset(Signal::SIGSEGV)) 54 .union(Signal::into_sigset(Signal::SIGBUS)) 55 .union(Signal::into_sigset(Signal::SIGTRAP)) 56 .union(Signal::into_sigset(Signal::SIGCHLD)) 57 .union(Signal::into_sigset(Signal::SIGIO_OR_POLL)) 58 .union(Signal::into_sigset(Signal::SIGSYS)); 59 60 /// SignalStruct 在 pcb 中加锁 61 #[derive(Debug)] 62 pub struct SignalStruct { 63 inner: Box<InnerSignalStruct>, 64 } 65 66 #[derive(Debug)] 67 pub struct InnerSignalStruct { 68 pub cnt: AtomicI64, 69 /// 如果对应linux,这部分会有一个引用计数,但是没发现在哪里有用到需要计算引用的地方,因此 70 /// 暂时删掉,不然这个Arc会导致其他地方的代码十分丑陋 71 pub handlers: [Sigaction; MAX_SIG_NUM as usize], 72 } 73 74 impl SignalStruct { 75 #[inline(never)] new() -> Self76 pub fn new() -> Self { 77 Self { 78 inner: Box::new(InnerSignalStruct::default()), 79 } 80 } 81 } 82 83 impl Deref for SignalStruct { 84 type Target = InnerSignalStruct; 85 deref(&self) -> &Self::Target86 fn deref(&self) -> &Self::Target { 87 &self.inner 88 } 89 } 90 91 impl DerefMut for SignalStruct { deref_mut(&mut self) -> &mut Self::Target92 fn deref_mut(&mut self) -> &mut Self::Target { 93 &mut self.inner 94 } 95 } 96 97 impl Default for InnerSignalStruct { default() -> Self98 fn default() -> Self { 99 Self { 100 cnt: Default::default(), 101 handlers: [Sigaction::default(); MAX_SIG_NUM as usize], 102 } 103 } 104 } 105 106 #[derive(Debug, Copy, Clone)] 107 #[allow(dead_code)] 108 pub enum SigactionType { 109 SaHandler(SaHandlerType), 110 SaSigaction( 111 Option< 112 unsafe extern "C" fn( 113 sig: ::core::ffi::c_int, 114 sinfo: *mut SigInfo, 115 arg1: *mut ::core::ffi::c_void, 116 ), 117 >, 118 ), // 暂时没有用上 119 } 120 121 impl SigactionType { 122 /// Returns `true` if the sa handler type is [`SaHandler(SaHandlerType::SigIgnore)`]. 123 /// 124 /// [`SigIgnore`]: SaHandlerType::SigIgnore is_ignore(&self) -> bool125 pub fn is_ignore(&self) -> bool { 126 return matches!(self, Self::SaHandler(SaHandlerType::SigIgnore)); 127 } 128 /// Returns `true` if the sa handler type is [`SaHandler(SaHandlerType::SigCustomized(_))`]. 129 /// 130 /// [`SigCustomized`]: SaHandlerType::SigCustomized(_) is_customized(&self) -> bool131 pub fn is_customized(&self) -> bool { 132 return matches!(self, Self::SaHandler(SaHandlerType::SigCustomized(_))); 133 } 134 } 135 136 #[derive(Debug, Copy, Clone)] 137 #[allow(dead_code)] 138 pub enum SaHandlerType { 139 SigError, // 暂时没有用上 140 SigDefault, 141 SigIgnore, 142 SigCustomized(VirtAddr), 143 } 144 145 impl Into<usize> for SaHandlerType { into(self) -> usize146 fn into(self) -> usize { 147 match self { 148 Self::SigError => 2 as usize, 149 Self::SigIgnore => 1 as usize, 150 Self::SigDefault => 0 as usize, 151 Self::SigCustomized(handler) => handler.data(), 152 } 153 } 154 } 155 156 impl SaHandlerType { 157 /// Returns `true` if the sa handler type is [`SigDefault`]. 158 /// 159 /// [`SigDefault`]: SaHandlerType::SigDefault is_sig_default(&self) -> bool160 pub fn is_sig_default(&self) -> bool { 161 matches!(self, Self::SigDefault) 162 } 163 164 /// Returns `true` if the sa handler type is [`SigIgnore`]. 165 /// 166 /// [`SigIgnore`]: SaHandlerType::SigIgnore is_sig_ignore(&self) -> bool167 pub fn is_sig_ignore(&self) -> bool { 168 matches!(self, Self::SigIgnore) 169 } 170 171 /// Returns `true` if the sa handler type is [`SigError`]. 172 /// 173 /// [`SigError`]: SaHandlerType::SigError is_sig_error(&self) -> bool174 pub fn is_sig_error(&self) -> bool { 175 matches!(self, Self::SigError) 176 } 177 } 178 179 /// 信号处理结构体 180 /// 181 #[derive(Debug, Copy, Clone)] 182 pub struct Sigaction { 183 action: SigactionType, 184 flags: SigFlags, 185 mask: SigSet, // 为了可扩展性而设置的sa_mask 186 /// 信号处理函数执行结束后,将会跳转到这个函数内进行执行,然后执行sigreturn系统调用 187 restorer: Option<VirtAddr>, 188 } 189 190 impl Default for Sigaction { default() -> Self191 fn default() -> Self { 192 Self { 193 action: SigactionType::SaHandler(SaHandlerType::SigDefault), 194 flags: Default::default(), 195 mask: Default::default(), 196 restorer: Default::default(), 197 } 198 } 199 } 200 201 impl Sigaction { 202 /// 判断传入的信号是否被忽略 203 /// 204 /// ## 参数 205 /// 206 /// - `sig` 传入的信号 207 /// 208 /// ## 返回值 209 /// 210 /// - `true` 被忽略 211 /// - `false`未被忽略 is_ignore(&self) -> bool212 pub fn is_ignore(&self) -> bool { 213 return self.action.is_ignore(); 214 } new( action: SigactionType, flags: SigFlags, mask: SigSet, restorer: Option<VirtAddr>, ) -> Self215 pub fn new( 216 action: SigactionType, 217 flags: SigFlags, 218 mask: SigSet, 219 restorer: Option<VirtAddr>, 220 ) -> Self { 221 Self { 222 action, 223 flags, 224 mask, 225 restorer, 226 } 227 } 228 action(&self) -> SigactionType229 pub fn action(&self) -> SigactionType { 230 self.action 231 } 232 flags(&self) -> SigFlags233 pub fn flags(&self) -> SigFlags { 234 self.flags 235 } 236 restorer(&self) -> Option<VirtAddr>237 pub fn restorer(&self) -> Option<VirtAddr> { 238 self.restorer 239 } 240 flags_mut(&mut self) -> &mut SigFlags241 pub fn flags_mut(&mut self) -> &mut SigFlags { 242 &mut self.flags 243 } 244 set_action(&mut self, action: SigactionType)245 pub fn set_action(&mut self, action: SigactionType) { 246 self.action = action; 247 } 248 mask(&self) -> SigSet249 pub fn mask(&self) -> SigSet { 250 self.mask 251 } 252 mask_mut(&mut self) -> &mut SigSet253 pub fn mask_mut(&mut self) -> &mut SigSet { 254 &mut self.mask 255 } 256 set_restorer(&mut self, restorer: Option<VirtAddr>)257 pub fn set_restorer(&mut self, restorer: Option<VirtAddr>) { 258 self.restorer = restorer; 259 } 260 261 /// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位) 262 pub const DEFAULT_SIGACTION: Sigaction = Sigaction { 263 action: SigactionType::SaHandler(SaHandlerType::SigDefault), 264 flags: SigFlags::empty(), 265 mask: SigSet::from_bits_truncate(0), 266 restorer: None, 267 }; 268 269 /// 默认的“忽略信号”的sigaction 270 pub const DEFAULT_SIGACTION_IGNORE: Sigaction = Sigaction { 271 action: SigactionType::SaHandler(SaHandlerType::SigIgnore), 272 flags: SigFlags::empty(), 273 mask: SigSet::from_bits_truncate(0), 274 restorer: None, 275 }; 276 } 277 278 /// 用户态传入的sigaction结构体(符合posix规范) 279 /// 请注意,我们会在sys_sigaction函数里面将其转换成内核使用的sigaction结构体 280 #[repr(C)] 281 #[derive(Debug, Clone, Copy)] 282 pub struct UserSigaction { 283 pub handler: *mut core::ffi::c_void, 284 pub flags: SigFlags, 285 pub restorer: *mut core::ffi::c_void, 286 pub mask: SigSet, 287 } 288 289 /** 290 * siginfo中,根据signal的来源不同,该info中对应了不同的数据./= 291 * 请注意,该info最大占用16字节 292 */ 293 294 #[repr(C)] 295 #[derive(Copy, Clone, Debug)] 296 pub struct SigInfo { 297 sig_no: i32, 298 sig_code: SigCode, 299 errno: i32, 300 sig_type: SigType, 301 } 302 303 impl SigInfo { sig_code(&self) -> SigCode304 pub fn sig_code(&self) -> SigCode { 305 self.sig_code 306 } 307 set_sig_type(&mut self, sig_type: SigType)308 pub fn set_sig_type(&mut self, sig_type: SigType) { 309 self.sig_type = sig_type; 310 } 311 /// @brief 将siginfo结构体拷贝到用户栈 312 /// ## 参数 313 /// 314 /// `to` 用户空间指针 315 /// 316 /// ## 注意 317 /// 318 /// 该函数对应Linux中的https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#3323 319 /// Linux还提供了 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#3383 用来实现 320 /// kernel_siginfo 保存到 用户的 compact_siginfo 的功能,但是我们系统内还暂时没有对这两种 321 /// siginfo做区分,因此暂时不需要第二个函数 copy_siginfo_to_user(&self, to: *mut SigInfo) -> Result<i32, SystemError>322 pub fn copy_siginfo_to_user(&self, to: *mut SigInfo) -> Result<i32, SystemError> { 323 // 验证目标地址是否为用户空间 324 let mut user_buffer = UserBufferWriter::new(to, size_of::<SigInfo>(), true)?; 325 326 let retval: Result<i32, SystemError> = Ok(0); 327 328 user_buffer.copy_one_to_user(self, 0)?; 329 return retval; 330 } 331 } 332 333 #[derive(Copy, Clone, Debug)] 334 pub enum SigType { 335 Kill(Pid), 336 // 后续完善下列中的具体字段 337 // Timer, 338 // Rt, 339 // SigChild, 340 // SigFault, 341 // SigPoll, 342 // SigSys, 343 } 344 345 impl SigInfo { new(sig: Signal, sig_errno: i32, sig_code: SigCode, sig_type: SigType) -> Self346 pub fn new(sig: Signal, sig_errno: i32, sig_code: SigCode, sig_type: SigType) -> Self { 347 Self { 348 sig_no: sig as i32, 349 sig_code, 350 errno: sig_errno, 351 sig_type, 352 } 353 } 354 } 355 356 #[derive(Debug)] 357 pub struct SigPending { 358 signal: SigSet, 359 queue: SigQueue, 360 } 361 362 impl Default for SigPending { default() -> Self363 fn default() -> Self { 364 SigPending { 365 signal: SigSet::default(), 366 queue: SigQueue::default(), 367 } 368 } 369 } 370 371 impl SigPending { 372 /// 判断是否有待处理的信号 has_pending(&self) -> bool373 pub fn has_pending(&self) -> bool { 374 return !self.signal.is_empty(); 375 } 376 signal(&self) -> SigSet377 pub fn signal(&self) -> SigSet { 378 self.signal 379 } 380 queue(&self) -> &SigQueue381 pub fn queue(&self) -> &SigQueue { 382 &self.queue 383 } 384 queue_mut(&mut self) -> &mut SigQueue385 pub fn queue_mut(&mut self) -> &mut SigQueue { 386 &mut self.queue 387 } 388 signal_mut(&mut self) -> &mut SigSet389 pub fn signal_mut(&mut self) -> &mut SigSet { 390 &mut self.signal 391 } 392 /// @brief 获取下一个要处理的信号(sig number越小的信号,优先级越高) 393 /// 394 /// @param pending 等待处理的信号 395 /// @param sig_mask 屏蔽了的信号 396 /// @return i32 下一个要处理的信号的number. 如果为0,则无效 next_signal(&self, sig_mask: &SigSet) -> Signal397 pub fn next_signal(&self, sig_mask: &SigSet) -> Signal { 398 let mut sig = Signal::INVALID; 399 400 let s = self.signal(); 401 let m = *sig_mask; 402 m.is_empty(); 403 // 获取第一个待处理的信号的号码 404 let x = s & (!m); 405 if x.bits() != 0 { 406 sig = Signal::from(ffz(x.complement().bits()) + 1); 407 return sig; 408 } 409 410 // 暂时只支持64种信号 411 assert_eq!(MAX_SIG_NUM, 64); 412 413 return sig; 414 } 415 /// @brief 收集信号的信息 416 /// 417 /// @param sig 要收集的信号的信息 418 /// @param pending 信号的排队等待标志 419 /// @return SigInfo 信号的信息 collect_signal(&mut self, sig: Signal) -> SigInfo420 pub fn collect_signal(&mut self, sig: Signal) -> SigInfo { 421 let (info, still_pending) = self.queue_mut().find_and_delete(sig); 422 423 // 如果没有仍在等待的信号,则清除pending位 424 if !still_pending { 425 self.signal_mut().remove(sig.into()); 426 } 427 428 if info.is_some() { 429 return info.unwrap(); 430 } else { 431 // 信号不在sigqueue中,这意味着当前信号是来自快速路径,因此直接把siginfo设置为0即可。 432 let mut ret = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(Pid::from(0))); 433 ret.set_sig_type(SigType::Kill(Pid::new(0))); 434 return ret; 435 } 436 } 437 438 /// @brief 从当前进程的sigpending中取出下一个待处理的signal,并返回给调用者。(调用者应当处理这个信号) 439 /// 请注意,进入本函数前,当前进程应当持有current_pcb().sighand.siglock dequeue_signal(&mut self, sig_mask: &SigSet) -> (Signal, Option<SigInfo>)440 pub fn dequeue_signal(&mut self, sig_mask: &SigSet) -> (Signal, Option<SigInfo>) { 441 // kdebug!("dequeue signal"); 442 // 获取下一个要处理的信号的编号 443 let sig = self.next_signal(sig_mask); 444 445 let info: Option<SigInfo>; 446 if sig != Signal::INVALID { 447 // 如果下一个要处理的信号是合法的,则收集其siginfo 448 info = Some(self.collect_signal(sig)); 449 } else { 450 info = None; 451 } 452 453 // 当一个进程具有多个线程之后,在这里需要重新计算线程的flag中的TIF_SIGPENDING位 454 // recalc_sigpending(); 455 return (sig, info); 456 } 457 /// @brief 从sigpending中删除mask中被置位的信号。也就是说,比如mask的第1位被置为1,那么就从sigqueue中删除所有signum为2的信号的信息。 flush_by_mask(&mut self, mask: &SigSet)458 pub fn flush_by_mask(&mut self, mask: &SigSet) { 459 // 定义过滤器,从sigqueue中删除mask中被置位的信号 460 let filter = |x: &SigInfo| !mask.contains(SigSet::from_bits_truncate(x.sig_no as u64)); 461 self.queue.q.retain(filter); 462 } 463 } 464 465 /// @brief 进程接收到的信号的队列 466 #[derive(Debug, Clone)] 467 pub struct SigQueue { 468 pub q: Vec<SigInfo>, 469 } 470 471 #[allow(dead_code)] 472 impl SigQueue { 473 /// @brief 初始化一个新的信号队列 new(capacity: usize) -> Self474 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) find(&self, sig: Signal) -> (Option<&SigInfo>, bool)483 pub fn find(&self, sig: Signal) -> (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 x.sig_no == 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) find_and_delete(&mut self, sig: Signal) -> (Option<SigInfo>, bool)504 pub fn find_and_delete(&mut self, sig: Signal) -> (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 x.sig_no == 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 } 521 return false; 522 }; 523 // 从sigqueue中过滤出结果 524 let mut filter_result: Vec<SigInfo> = self.q.extract_if(filter).collect(); 525 // 筛选出的结果不能大于1个 526 assert!(filter_result.len() <= 1); 527 528 return (filter_result.pop(), still_pending); 529 } 530 531 /// @brief 从C的void*指针转换为static生命周期的可变引用 from_c_void(p: *mut c_void) -> &'static mut SigQueue532 pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue { 533 let sq = p as *mut SigQueue; 534 let sq = unsafe { sq.as_mut::<'static>() }.unwrap(); 535 return sq; 536 } 537 } 538 539 impl Default for SigQueue { default() -> Self540 fn default() -> Self { 541 Self { 542 q: Default::default(), 543 } 544 } 545 } 546 547 /// 548 /// 定义了不同架构下实现 Signal 要实现的接口 549 /// 550 pub trait SignalArch { 551 /// 信号处理函数 552 /// 553 /// ## 参数 554 /// 555 /// - `frame` 中断栈帧 do_signal(frame: &mut TrapFrame)556 unsafe fn do_signal(frame: &mut TrapFrame); 557 sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64558 fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64; 559 } 560