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