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 #[allow(dead_code)] 68 pub struct InnerSignalStruct { 69 pub cnt: AtomicI64, 70 /// 如果对应linux,这部分会有一个引用计数,但是没发现在哪里有用到需要计算引用的地方,因此 71 /// 暂时删掉,不然这个Arc会导致其他地方的代码十分丑陋 72 pub handlers: [Sigaction; MAX_SIG_NUM], 73 } 74 75 impl SignalStruct { 76 #[inline(never)] 77 pub fn new() -> Self { 78 Self { 79 inner: Box::<InnerSignalStruct>::default(), 80 } 81 } 82 } 83 84 impl Deref for SignalStruct { 85 type Target = InnerSignalStruct; 86 87 fn deref(&self) -> &Self::Target { 88 &self.inner 89 } 90 } 91 92 impl DerefMut for SignalStruct { 93 fn deref_mut(&mut self) -> &mut Self::Target { 94 &mut self.inner 95 } 96 } 97 98 impl Default for InnerSignalStruct { 99 fn default() -> Self { 100 Self { 101 cnt: Default::default(), 102 handlers: [Sigaction::default(); MAX_SIG_NUM], 103 } 104 } 105 } 106 107 #[derive(Debug, Copy, Clone)] 108 #[allow(dead_code)] 109 pub enum SigactionType { 110 SaHandler(SaHandlerType), 111 SaSigaction( 112 Option< 113 unsafe extern "C" fn( 114 sig: ::core::ffi::c_int, 115 sinfo: *mut SigInfo, 116 arg1: *mut ::core::ffi::c_void, 117 ), 118 >, 119 ), // 暂时没有用上 120 } 121 122 impl SigactionType { 123 /// Returns `true` if the sa handler type is [`SaHandler(SaHandlerType::SigIgnore)`]. 124 /// 125 /// [`SigIgnore`]: SaHandlerType::SigIgnore 126 pub fn is_ignore(&self) -> bool { 127 return matches!(self, Self::SaHandler(SaHandlerType::Ignore)); 128 } 129 /// Returns `true` if the sa handler type is [`SaHandler(SaHandlerType::SigCustomized(_))`]. 130 /// 131 /// [`SigCustomized`]: SaHandlerType::SigCustomized(_) 132 pub fn is_customized(&self) -> bool { 133 return matches!(self, Self::SaHandler(SaHandlerType::Customized(_))); 134 } 135 } 136 137 #[derive(Debug, Copy, Clone)] 138 #[allow(dead_code)] 139 pub enum SaHandlerType { 140 Error, // 暂时没有用上 141 Default, 142 Ignore, 143 Customized(VirtAddr), 144 } 145 146 impl From<SaHandlerType> for usize { 147 fn from(value: SaHandlerType) -> Self { 148 match value { 149 SaHandlerType::Error => 2, 150 SaHandlerType::Ignore => 1, 151 SaHandlerType::Default => 0, 152 SaHandlerType::Customized(handler) => handler.data(), 153 } 154 } 155 } 156 157 impl SaHandlerType { 158 /// Returns `true` if the sa handler type is [`SigDefault`]. 159 /// 160 /// [`SigDefault`]: SaHandlerType::SigDefault 161 pub fn is_sig_default(&self) -> bool { 162 matches!(self, Self::Default) 163 } 164 165 /// Returns `true` if the sa handler type is [`SigIgnore`]. 166 /// 167 /// [`SigIgnore`]: SaHandlerType::SigIgnore 168 pub fn is_sig_ignore(&self) -> bool { 169 matches!(self, Self::Ignore) 170 } 171 172 /// Returns `true` if the sa handler type is [`SigError`]. 173 /// 174 /// [`SigError`]: SaHandlerType::SigError 175 pub fn is_sig_error(&self) -> bool { 176 matches!(self, Self::Error) 177 } 178 } 179 180 /// 信号处理结构体 181 /// 182 #[derive(Debug, Copy, Clone)] 183 pub struct Sigaction { 184 action: SigactionType, 185 flags: SigFlags, 186 mask: SigSet, // 为了可扩展性而设置的sa_mask 187 /// 信号处理函数执行结束后,将会跳转到这个函数内进行执行,然后执行sigreturn系统调用 188 restorer: Option<VirtAddr>, 189 } 190 191 impl Default for Sigaction { 192 fn default() -> Self { 193 Self { 194 action: SigactionType::SaHandler(SaHandlerType::Default), 195 flags: Default::default(), 196 mask: Default::default(), 197 restorer: Default::default(), 198 } 199 } 200 } 201 202 impl Sigaction { 203 /// 判断传入的信号是否被忽略 204 /// 205 /// ## 参数 206 /// 207 /// - `sig` 传入的信号 208 /// 209 /// ## 返回值 210 /// 211 /// - `true` 被忽略 212 /// - `false`未被忽略 213 pub fn is_ignore(&self) -> bool { 214 return self.action.is_ignore(); 215 } 216 pub fn new( 217 action: SigactionType, 218 flags: SigFlags, 219 mask: SigSet, 220 restorer: Option<VirtAddr>, 221 ) -> Self { 222 Self { 223 action, 224 flags, 225 mask, 226 restorer, 227 } 228 } 229 230 pub fn action(&self) -> SigactionType { 231 self.action 232 } 233 234 pub fn flags(&self) -> SigFlags { 235 self.flags 236 } 237 238 pub fn restorer(&self) -> Option<VirtAddr> { 239 self.restorer 240 } 241 242 pub fn flags_mut(&mut self) -> &mut SigFlags { 243 &mut self.flags 244 } 245 246 pub fn set_action(&mut self, action: SigactionType) { 247 self.action = action; 248 } 249 250 pub fn mask(&self) -> SigSet { 251 self.mask 252 } 253 254 pub fn mask_mut(&mut self) -> &mut SigSet { 255 &mut self.mask 256 } 257 258 pub fn set_restorer(&mut self, restorer: Option<VirtAddr>) { 259 self.restorer = restorer; 260 } 261 262 /// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位) 263 pub const DEFAULT_SIGACTION: Sigaction = Sigaction { 264 action: SigactionType::SaHandler(SaHandlerType::Default), 265 flags: SigFlags::empty(), 266 mask: SigSet::from_bits_truncate(0), 267 restorer: None, 268 }; 269 270 /// 默认的“忽略信号”的sigaction 271 pub const DEFAULT_SIGACTION_IGNORE: Sigaction = Sigaction { 272 action: SigactionType::SaHandler(SaHandlerType::Ignore), 273 flags: SigFlags::empty(), 274 mask: SigSet::from_bits_truncate(0), 275 restorer: None, 276 }; 277 } 278 279 /// 用户态传入的sigaction结构体(符合posix规范) 280 /// 请注意,我们会在sys_sigaction函数里面将其转换成内核使用的sigaction结构体 281 #[repr(C)] 282 #[derive(Debug, Clone, Copy)] 283 pub struct UserSigaction { 284 pub handler: *mut core::ffi::c_void, 285 pub flags: SigFlags, 286 pub restorer: *mut core::ffi::c_void, 287 pub mask: SigSet, 288 } 289 290 /** 291 * siginfo中,根据signal的来源不同,该info中对应了不同的数据./= 292 * 请注意,该info最大占用16字节 293 */ 294 295 #[repr(C)] 296 #[derive(Copy, Clone, Debug)] 297 pub struct SigInfo { 298 sig_no: i32, 299 sig_code: SigCode, 300 errno: i32, 301 sig_type: SigType, 302 } 303 304 impl SigInfo { 305 pub fn sig_code(&self) -> SigCode { 306 self.sig_code 307 } 308 309 pub fn set_sig_type(&mut self, sig_type: SigType) { 310 self.sig_type = sig_type; 311 } 312 /// @brief 将siginfo结构体拷贝到用户栈 313 /// ## 参数 314 /// 315 /// `to` 用户空间指针 316 /// 317 /// ## 注意 318 /// 319 /// 该函数对应Linux中的https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#3323 320 /// Linux还提供了 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#3383 用来实现 321 /// kernel_siginfo 保存到 用户的 compact_siginfo 的功能,但是我们系统内还暂时没有对这两种 322 /// siginfo做区分,因此暂时不需要第二个函数 323 pub fn copy_siginfo_to_user(&self, to: *mut SigInfo) -> Result<i32, SystemError> { 324 // 验证目标地址是否为用户空间 325 let mut user_buffer = UserBufferWriter::new(to, size_of::<SigInfo>(), true)?; 326 327 let retval: Result<i32, SystemError> = Ok(0); 328 329 user_buffer.copy_one_to_user(self, 0)?; 330 return retval; 331 } 332 } 333 334 #[derive(Copy, Clone, Debug)] 335 pub enum SigType { 336 Kill(Pid), 337 Alarm(Pid), 338 // 后续完善下列中的具体字段 339 // Timer, 340 // Rt, 341 // SigChild, 342 // SigFault, 343 // SigPoll, 344 // SigSys, 345 } 346 347 impl SigInfo { 348 pub fn new(sig: Signal, sig_errno: i32, sig_code: SigCode, sig_type: SigType) -> Self { 349 Self { 350 sig_no: sig as i32, 351 sig_code, 352 errno: sig_errno, 353 sig_type, 354 } 355 } 356 } 357 358 #[derive(Debug, Default)] 359 pub struct SigPending { 360 signal: SigSet, 361 queue: SigQueue, 362 } 363 364 impl SigPending { 365 /// 判断是否有待处理的信号 366 pub fn has_pending(&self) -> bool { 367 return !self.signal.is_empty(); 368 } 369 370 pub fn signal(&self) -> SigSet { 371 self.signal 372 } 373 374 pub fn queue(&self) -> &SigQueue { 375 &self.queue 376 } 377 378 pub fn queue_mut(&mut self) -> &mut SigQueue { 379 &mut self.queue 380 } 381 382 pub fn signal_mut(&mut self) -> &mut SigSet { 383 &mut self.signal 384 } 385 /// @brief 获取下一个要处理的信号(sig number越小的信号,优先级越高) 386 /// 387 /// @param pending 等待处理的信号 388 /// @param sig_mask 屏蔽了的信号 389 /// @return i32 下一个要处理的信号的number. 如果为0,则无效 390 pub fn next_signal(&self, sig_mask: &SigSet) -> Signal { 391 let mut sig = Signal::INVALID; 392 393 let s = self.signal(); 394 let m = *sig_mask; 395 m.is_empty(); 396 // 获取第一个待处理的信号的号码 397 let x = s & (!m); 398 if x.bits() != 0 { 399 sig = Signal::from(ffz(x.complement().bits()) + 1); 400 return sig; 401 } 402 403 // 暂时只支持64种信号 404 assert_eq!(MAX_SIG_NUM, 64); 405 406 return sig; 407 } 408 /// @brief 收集信号的信息 409 /// 410 /// @param sig 要收集的信号的信息 411 /// @param pending 信号的排队等待标志 412 /// @return SigInfo 信号的信息 413 pub fn collect_signal(&mut self, sig: Signal) -> SigInfo { 414 let (info, still_pending) = self.queue_mut().find_and_delete(sig); 415 416 // 如果没有仍在等待的信号,则清除pending位 417 if !still_pending { 418 self.signal_mut().remove(sig.into()); 419 } 420 421 if let Some(info) = info { 422 return info; 423 } else { 424 // 信号不在sigqueue中,这意味着当前信号是来自快速路径,因此直接把siginfo设置为0即可。 425 let mut ret = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(Pid::from(0))); 426 ret.set_sig_type(SigType::Kill(Pid::new(0))); 427 return ret; 428 } 429 } 430 431 /// @brief 从当前进程的sigpending中取出下一个待处理的signal,并返回给调用者。(调用者应当处理这个信号) 432 /// 请注意,进入本函数前,当前进程应当持有current_pcb().sighand.siglock 433 pub fn dequeue_signal(&mut self, sig_mask: &SigSet) -> (Signal, Option<SigInfo>) { 434 // debug!("dequeue signal"); 435 // 获取下一个要处理的信号的编号 436 let sig = self.next_signal(sig_mask); 437 438 let info: Option<SigInfo> = if sig != Signal::INVALID { 439 // 如果下一个要处理的信号是合法的,则收集其siginfo 440 Some(self.collect_signal(sig)) 441 } else { 442 None 443 }; 444 445 // 当一个进程具有多个线程之后,在这里需要重新计算线程的flag中的TIF_SIGPENDING位 446 // recalc_sigpending(); 447 return (sig, info); 448 } 449 /// @brief 从sigpending中删除mask中被置位的信号。也就是说,比如mask的第1位被置为1,那么就从sigqueue中删除所有signum为2的信号的信息。 450 pub fn flush_by_mask(&mut self, mask: &SigSet) { 451 // 定义过滤器,从sigqueue中删除mask中被置位的信号 452 let filter = |x: &SigInfo| !mask.contains(SigSet::from_bits_truncate(x.sig_no as u64)); 453 self.queue.q.retain(filter); 454 } 455 } 456 457 /// @brief 进程接收到的信号的队列 458 #[derive(Debug, Clone, Default)] 459 pub struct SigQueue { 460 pub q: Vec<SigInfo>, 461 } 462 463 #[allow(dead_code)] 464 impl SigQueue { 465 /// @brief 初始化一个新的信号队列 466 pub fn new(capacity: usize) -> Self { 467 SigQueue { 468 q: Vec::with_capacity(capacity), 469 } 470 } 471 472 /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并返回它的引用 473 /// 474 /// @return (第一个满足要求的siginfo的引用; 是否有多个满足条件的siginfo) 475 pub fn find(&self, sig: Signal) -> (Option<&SigInfo>, bool) { 476 // 是否存在多个满足条件的siginfo 477 let mut still_pending = false; 478 let mut info: Option<&SigInfo> = None; 479 480 for x in self.q.iter() { 481 if x.sig_no == sig as i32 { 482 if info.is_some() { 483 still_pending = true; 484 break; 485 } else { 486 info = Some(x); 487 } 488 } 489 } 490 return (info, still_pending); 491 } 492 493 /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并将其从队列中删除,然后返回这个siginfo 494 /// 495 /// @return (第一个满足要求的siginfo; 从队列中删除前是否有多个满足条件的siginfo) 496 pub fn find_and_delete(&mut self, sig: Signal) -> (Option<SigInfo>, bool) { 497 // 是否存在多个满足条件的siginfo 498 let mut still_pending = false; 499 let mut first = true; // 标记变量,记录当前是否已经筛选出了一个元素 500 501 let filter = |x: &mut SigInfo| { 502 if x.sig_no == sig as i32 { 503 if !first { 504 // 如果之前已经筛选出了一个元素,则不把当前元素删除 505 still_pending = true; 506 return false; 507 } else { 508 // 当前是第一个被筛选出来的元素 509 first = false; 510 return true; 511 } 512 } 513 return false; 514 }; 515 // 从sigqueue中过滤出结果 516 let mut filter_result: Vec<SigInfo> = self.q.extract_if(filter).collect(); 517 // 筛选出的结果不能大于1个 518 assert!(filter_result.len() <= 1); 519 520 return (filter_result.pop(), still_pending); 521 } 522 523 /// @brief 从C的void*指针转换为static生命周期的可变引用 524 pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue { 525 let sq = p as *mut SigQueue; 526 let sq = unsafe { sq.as_mut::<'static>() }.unwrap(); 527 return sq; 528 } 529 } 530 531 /// 532 /// 定义了不同架构下实现 Signal 要实现的接口 533 /// 534 pub trait SignalArch { 535 /// 信号处理函数 536 /// 537 /// ## 参数 538 /// 539 /// - `frame` 中断栈帧 540 unsafe fn do_signal(frame: &mut TrapFrame); 541 542 fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64; 543 } 544