signal.rs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. use core::{fmt::Debug, sync::atomic::compiler_fence};
  2. use alloc::sync::Arc;
  3. use log::warn;
  4. use system_error::SystemError;
  5. use crate::{
  6. arch::ipc::signal::{SigCode, SigFlags, SigSet, Signal},
  7. ipc::signal_types::SigactionType,
  8. libs::spinlock::SpinLockGuard,
  9. mm::VirtAddr,
  10. process::{
  11. pid::PidType, Pid, ProcessControlBlock, ProcessFlags, ProcessManager, ProcessSignalInfo,
  12. },
  13. time::Instant,
  14. };
  15. use super::signal_types::{
  16. SaHandlerType, SigInfo, SigType, Sigaction, SignalStruct, SIG_KERNEL_STOP_MASK,
  17. };
  18. impl Signal {
  19. pub fn signal_pending_state(
  20. interruptible: bool,
  21. task_wake_kill: bool,
  22. pcb: &Arc<ProcessControlBlock>,
  23. ) -> bool {
  24. if !interruptible && !task_wake_kill {
  25. return false;
  26. }
  27. if !pcb.has_pending_signal_fast() {
  28. return false;
  29. }
  30. return interruptible || Self::fatal_signal_pending(pcb);
  31. }
  32. /// 判断当前进程是否收到了SIGKILL信号
  33. pub fn fatal_signal_pending(pcb: &Arc<ProcessControlBlock>) -> bool {
  34. let guard = pcb.sig_info_irqsave();
  35. if guard
  36. .sig_pending()
  37. .signal()
  38. .contains(Signal::SIGKILL.into())
  39. {
  40. return true;
  41. }
  42. return false;
  43. }
  44. /// 向目标进程发送信号
  45. ///
  46. /// ## 参数
  47. ///
  48. /// - `sig` 要发送的信号
  49. /// - `info` 要发送的信息
  50. /// - `pid` 进程id(目前只支持pid>0)
  51. pub fn send_signal_info(
  52. &self,
  53. info: Option<&mut SigInfo>,
  54. pid: Pid,
  55. ) -> Result<i32, SystemError> {
  56. // TODO:暂时不支持特殊的信号操作,待引入进程组后补充
  57. // 如果 pid 大于 0,那么会发送信号给 pid 指定的进程
  58. // 如果 pid 等于 0,那么会发送信号给与调用进程同组的每个进程,包括调用进程自身
  59. // 如果 pid 小于 -1,那么会向组 ID 等于该 pid 绝对值的进程组内所有下属进程发送信号。向一个进程组的所有进程发送信号在 shell 作业控制中有特殊有途
  60. // 如果 pid 等于 -1,那么信号的发送范围是:调用进程有权将信号发往的每个目标进程,除去 init(进程 ID 为 1)和调用进程自身。如果特权级进程发起这一调用,那么会发送信号给系统中的所有进程,上述两个进程除外。显而易见,有时也将这种信号发送方式称之为广播信号
  61. // 如果并无进程与指定的 pid 相匹配,那么 kill() 调用失败,同时将 errno 置为 ESRCH(“查无此进程”)
  62. if pid.lt(&Pid::from(0)) {
  63. warn!("Kill operation not support: pid={:?}", pid);
  64. return Err(SystemError::ENOSYS);
  65. }
  66. // 暂时不支持发送信号给进程组
  67. if pid.data() == 0 {
  68. return Err(SystemError::ENOSYS);
  69. }
  70. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  71. // 检查sig是否符合要求,如果不符合要求,则退出。
  72. if !self.is_valid() {
  73. return Err(SystemError::EINVAL);
  74. }
  75. let mut retval = Err(SystemError::ESRCH);
  76. let pcb = ProcessManager::find(pid);
  77. if pcb.is_none() {
  78. warn!("No such process: pid={:?}", pid);
  79. return retval;
  80. }
  81. let pcb = pcb.unwrap();
  82. // println!("Target pcb = {:?}", pcb.as_ref().unwrap());
  83. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  84. // 发送信号
  85. retval = self.send_signal(info, pcb.clone(), PidType::PID);
  86. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  87. return retval;
  88. }
  89. /// @brief 判断是否需要强制发送信号,然后发送信号
  90. /// 进入函数后加锁
  91. ///
  92. /// @return SystemError 错误码
  93. fn send_signal(
  94. &self,
  95. info: Option<&mut SigInfo>,
  96. pcb: Arc<ProcessControlBlock>,
  97. pt: PidType,
  98. ) -> Result<i32, SystemError> {
  99. // 是否强制发送信号
  100. let mut force_send = false;
  101. // signal的信息为空
  102. if let Some(ref siginfo) = info {
  103. force_send = matches!(siginfo.sig_code(), SigCode::Kernel);
  104. } else {
  105. // todo: 判断signal是否来自于一个祖先进程的namespace,如果是,则强制发送信号
  106. //详见 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c?r=&mo=32170&fi=1220#1226
  107. }
  108. if !self.prepare_sianal(pcb.clone(), force_send) {
  109. return Ok(0);
  110. }
  111. // debug!("force send={}", force_send);
  112. let pcb_info = pcb.sig_info_irqsave();
  113. let pending = if matches!(pt, PidType::PID) {
  114. pcb_info.sig_shared_pending()
  115. } else {
  116. pcb_info.sig_pending()
  117. };
  118. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  119. // 如果是kill或者目标pcb是内核线程,则无需获取sigqueue,直接发送信号即可
  120. if matches!(self, Signal::SIGKILL) || pcb.flags().contains(ProcessFlags::KTHREAD) {
  121. //避免死锁
  122. drop(pcb_info);
  123. self.complete_signal(pcb.clone(), pt);
  124. }
  125. // 如果不是实时信号的话,同一时刻信号队列里只会有一个待处理的信号,如果重复接收就不做处理
  126. else if !self.is_rt_signal() && pending.queue().find(*self).0.is_some() {
  127. return Ok(0);
  128. } else {
  129. // TODO signalfd_notify 完善 signalfd 机制
  130. // 如果是其他信号,则加入到sigqueue内,然后complete_signal
  131. let new_sig_info = match info {
  132. Some(siginfo) => {
  133. // 已经显式指定了siginfo,则直接使用它。
  134. *siginfo
  135. }
  136. None => {
  137. // 不需要显示指定siginfo,因此设置为默认值
  138. SigInfo::new(
  139. *self,
  140. 0,
  141. SigCode::User,
  142. SigType::Kill(ProcessManager::current_pcb().pid()),
  143. )
  144. }
  145. };
  146. drop(pcb_info);
  147. pcb.sig_info_mut()
  148. .sig_pending_mut()
  149. .queue_mut()
  150. .q
  151. .push(new_sig_info);
  152. // if pt == PidType::PGID || pt == PidType::SID {}
  153. self.complete_signal(pcb.clone(), pt);
  154. }
  155. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  156. return Ok(0);
  157. }
  158. /// @brief 将信号添加到目标进程的sig_pending。在引入进程组后,本函数还将负责把信号传递给整个进程组。
  159. ///
  160. /// @param sig 信号
  161. /// @param pcb 目标pcb
  162. /// @param pt siginfo结构体中,pid字段代表的含义
  163. #[allow(clippy::if_same_then_else)]
  164. fn complete_signal(&self, pcb: Arc<ProcessControlBlock>, pt: PidType) {
  165. // debug!("complete_signal");
  166. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  167. // ===== 寻找需要wakeup的目标进程 =====
  168. // 备注:由于当前没有进程组的概念,每个进程只有1个对应的线程,因此不需要通知进程组内的每个进程。
  169. // todo: 当引入进程组的概念后,需要完善这里,使得它能寻找一个目标进程来唤醒,接着执行信号处理的操作。
  170. // let _signal = pcb.sig_struct();
  171. let target_pcb: Option<Arc<ProcessControlBlock>>;
  172. // 判断目标进程是否想接收这个信号
  173. if self.wants_signal(pcb.clone()) {
  174. // todo: 将信号产生的消息通知到正在监听这个信号的进程(引入signalfd之后,在这里调用signalfd_notify)
  175. // 将这个信号加到目标进程的sig_pending中
  176. pcb.sig_info_mut()
  177. .sig_pending_mut()
  178. .signal_mut()
  179. .insert((*self).into());
  180. target_pcb = Some(pcb.clone());
  181. } else if pt == PidType::PID {
  182. /*
  183. * There is just one thread and it does not need to be woken.
  184. * It will dequeue unblocked signals before it runs again.
  185. */
  186. return;
  187. } else {
  188. /*
  189. * Otherwise try to find a suitable thread.
  190. * 由于目前每个进程只有1个线程,因此当前情况可以返回。信号队列的dequeue操作不需要考虑同步阻塞的问题。
  191. */
  192. return;
  193. }
  194. // TODO:引入进程组后,在这里挑选一个进程来唤醒,让它执行相应的操作。
  195. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  196. // TODO: 到这里,信号已经被放置在共享的pending队列中,我们在这里把目标进程唤醒。
  197. if let Some(target_pcb) = target_pcb {
  198. let guard = target_pcb.sig_struct();
  199. signal_wake_up(target_pcb.clone(), guard, *self == Signal::SIGKILL);
  200. }
  201. }
  202. /// 本函数用于检测指定的进程是否想要接收SIG这个信号。
  203. ///
  204. /// 当我们对于进程组中的所有进程都运行了这个检查之后,我们将可以找到组内愿意接收信号的进程。
  205. /// 这么做是为了防止我们把信号发送给了一个正在或已经退出的进程,或者是不响应该信号的进程。
  206. #[inline]
  207. fn wants_signal(&self, pcb: Arc<ProcessControlBlock>) -> bool {
  208. // 如果改进程屏蔽了这个signal,则不能接收
  209. if pcb
  210. .sig_info_irqsave()
  211. .sig_blocked()
  212. .contains((*self).into())
  213. {
  214. return false;
  215. }
  216. // 如果进程正在退出,则不能接收信号
  217. if pcb.flags().contains(ProcessFlags::EXITING) {
  218. return false;
  219. }
  220. if *self == Signal::SIGKILL {
  221. return true;
  222. }
  223. let state = pcb.sched_info().inner_lock_read_irqsave().state();
  224. if state.is_blocked() && (!state.is_blocked_interruptable()) {
  225. return false;
  226. }
  227. // todo: 检查目标进程是否正在一个cpu上执行,如果是,则返回true,否则继续检查下一项
  228. // 检查目标进程是否有信号正在等待处理,如果是,则返回false,否则返回true
  229. return pcb.sig_info_irqsave().sig_pending().signal().bits() == 0;
  230. }
  231. /// @brief 判断signal的处理是否可能使得整个进程组退出
  232. /// @return true 可能会导致退出(不一定)
  233. #[allow(dead_code)]
  234. #[inline]
  235. fn sig_fatal(&self, pcb: Arc<ProcessControlBlock>) -> bool {
  236. let action = pcb.sig_struct().handlers[*self as usize - 1].action();
  237. // 如果handler是空,采用默认函数,signal处理可能会导致进程退出。
  238. match action {
  239. SigactionType::SaHandler(handler) => handler.is_sig_default(),
  240. SigactionType::SaSigaction(sigaction) => sigaction.is_none(),
  241. }
  242. // todo: 参照linux的sig_fatal实现完整功能
  243. }
  244. /// 检查信号是否能被发送,并且而且要处理 SIGCONT 和 STOP 信号
  245. ///
  246. /// ## 参数
  247. ///
  248. /// - `pcb` 要发送信号的目标pcb
  249. ///
  250. /// - `force` 是否强制发送(指走 fast path , 不加入 sigpending按顺序处理,直接进入 complete_signal)
  251. ///
  252. /// ## 返回值
  253. ///
  254. /// - `true` 能够发送信号
  255. ///
  256. /// - `false` 不能发送信号
  257. fn prepare_sianal(&self, pcb: Arc<ProcessControlBlock>, _force: bool) -> bool {
  258. let flush: SigSet;
  259. if !(self.into_sigset() & SIG_KERNEL_STOP_MASK).is_empty() {
  260. flush = Signal::SIGCONT.into_sigset();
  261. pcb.sig_info_mut()
  262. .sig_shared_pending_mut()
  263. .flush_by_mask(&flush);
  264. // TODO 对每个子线程 flush mask
  265. } else if *self == Signal::SIGCONT {
  266. flush = SIG_KERNEL_STOP_MASK;
  267. assert!(!flush.is_empty());
  268. pcb.sig_info_mut()
  269. .sig_shared_pending_mut()
  270. .flush_by_mask(&flush);
  271. let _r = ProcessManager::wakeup_stop(&pcb);
  272. // TODO 对每个子线程 flush mask
  273. // 这里需要补充一段逻辑,详见https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#952
  274. }
  275. // 一个被阻塞了的信号肯定是要被处理的
  276. if pcb
  277. .sig_info_irqsave()
  278. .sig_blocked()
  279. .contains(self.into_sigset())
  280. {
  281. return true;
  282. }
  283. return !pcb.sig_struct().handlers[*self as usize - 1].is_ignore();
  284. //TODO 仿照 linux 中的prepare signal完善逻辑,linux 中还会根据例如当前进程状态(Existing)进行判断,现在的信号能否发出就只是根据 ignored 来判断
  285. }
  286. }
  287. /// 因收到信号而唤醒进程
  288. ///
  289. /// ## 参数
  290. ///
  291. /// - `pcb` 要唤醒的进程pcb
  292. /// - `_guard` 信号结构体锁守卫,来保证信号结构体已上锁
  293. /// - `fatal` 表明这个信号是不是致命的(会导致进程退出)
  294. #[inline]
  295. fn signal_wake_up(pcb: Arc<ProcessControlBlock>, _guard: SpinLockGuard<SignalStruct>, fatal: bool) {
  296. // 如果是 fatal 的话就唤醒 stop 和 block 的进程来响应,因为唤醒后就会终止
  297. // 如果不是 fatal 的就只唤醒 stop 的进程来响应
  298. // debug!("signal_wake_up");
  299. // 如果目标进程已经在运行,则发起一个ipi,使得它陷入内核
  300. let state = pcb.sched_info().inner_lock_read_irqsave().state();
  301. pcb.flags().insert(ProcessFlags::HAS_PENDING_SIGNAL);
  302. let mut wakeup_ok = true;
  303. if state.is_blocked_interruptable() {
  304. ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
  305. wakeup_ok = false;
  306. warn!(
  307. "Current pid: {:?}, signal_wake_up target {:?} error: {:?}",
  308. ProcessManager::current_pcb().pid(),
  309. pcb.pid(),
  310. e
  311. );
  312. });
  313. } else if state.is_stopped() {
  314. ProcessManager::wakeup_stop(&pcb).unwrap_or_else(|e| {
  315. wakeup_ok = false;
  316. warn!(
  317. "Current pid: {:?}, signal_wake_up target {:?} error: {:?}",
  318. ProcessManager::current_pcb().pid(),
  319. pcb.pid(),
  320. e
  321. );
  322. });
  323. } else {
  324. wakeup_ok = false;
  325. }
  326. if wakeup_ok {
  327. ProcessManager::kick(&pcb);
  328. } else if fatal {
  329. let _r = ProcessManager::wakeup(&pcb).map(|_| {
  330. ProcessManager::kick(&pcb);
  331. });
  332. }
  333. }
  334. fn has_pending_signals(sigset: &SigSet, blocked: &SigSet) -> bool {
  335. sigset.bits() & (!blocked.bits()) != 0
  336. }
  337. impl ProcessControlBlock {
  338. /// 重新计算线程的flag中的TIF_SIGPENDING位
  339. /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c?r=&mo=4806&fi=182#182
  340. pub fn recalc_sigpending(&self, siginfo_guard: Option<&ProcessSignalInfo>) {
  341. if !self.recalc_sigpending_tsk(siginfo_guard) {
  342. self.flags().remove(ProcessFlags::HAS_PENDING_SIGNAL);
  343. }
  344. }
  345. fn recalc_sigpending_tsk(&self, siginfo_guard: Option<&ProcessSignalInfo>) -> bool {
  346. let mut _siginfo_tmp_guard = None;
  347. let siginfo = if let Some(siginfo_guard) = siginfo_guard {
  348. siginfo_guard
  349. } else {
  350. _siginfo_tmp_guard = Some(self.sig_info_irqsave());
  351. _siginfo_tmp_guard.as_ref().unwrap()
  352. };
  353. return siginfo.do_recalc_sigpending_tsk(self);
  354. }
  355. }
  356. impl ProcessSignalInfo {
  357. fn do_recalc_sigpending_tsk(&self, pcb: &ProcessControlBlock) -> bool {
  358. if has_pending_signals(&self.sig_pending().signal(), self.sig_blocked())
  359. || has_pending_signals(&self.sig_shared_pending().signal(), self.sig_blocked())
  360. {
  361. pcb.flags().insert(ProcessFlags::HAS_PENDING_SIGNAL);
  362. return true;
  363. }
  364. /*
  365. * We must never clear the flag in another thread, or in current
  366. * when it's possible the current syscall is returning -ERESTART*.
  367. * So we don't clear it here, and only callers who know they should do.
  368. */
  369. return false;
  370. }
  371. }
  372. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/sched/signal.h?fi=restore_saved_sigmask#547
  373. pub fn restore_saved_sigmask() {
  374. if ProcessManager::current_pcb()
  375. .flags()
  376. .test_and_clear(ProcessFlags::RESTORE_SIG_MASK)
  377. {
  378. let saved = *ProcessManager::current_pcb()
  379. .sig_info_irqsave()
  380. .saved_sigmask();
  381. __set_current_blocked(&saved);
  382. }
  383. }
  384. /// 刷新指定进程的sighand的sigaction,将满足条件的sigaction恢复为默认状态。
  385. /// 除非某个信号被设置为忽略且 `force_default` 为 `false`,否则都不会将其恢复。
  386. ///
  387. /// # 参数
  388. ///
  389. /// - `pcb`: 要被刷新的pcb。
  390. /// - `force_default`: 是否强制将sigaction恢复成默认状态。
  391. pub fn flush_signal_handlers(pcb: Arc<ProcessControlBlock>, force_default: bool) {
  392. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  393. // debug!("hand=0x{:018x}", hand as *const sighand_struct as usize);
  394. let actions = &mut pcb.sig_struct_irqsave().handlers;
  395. for sigaction in actions.iter_mut() {
  396. if force_default || !sigaction.is_ignore() {
  397. sigaction.set_action(SigactionType::SaHandler(SaHandlerType::Default));
  398. }
  399. // 清除flags中,除了DFL和IGN以外的所有标志
  400. sigaction.set_restorer(None);
  401. sigaction.mask_mut().remove(SigSet::all());
  402. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  403. }
  404. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  405. }
  406. pub(super) fn do_sigaction(
  407. sig: Signal,
  408. act: Option<&mut Sigaction>,
  409. old_act: Option<&mut Sigaction>,
  410. ) -> Result<(), SystemError> {
  411. if sig == Signal::INVALID {
  412. return Err(SystemError::EINVAL);
  413. }
  414. let pcb = ProcessManager::current_pcb();
  415. // 指向当前信号的action的引用
  416. let action: &mut Sigaction = &mut pcb.sig_struct().handlers[sig as usize - 1];
  417. // 对比 MUSL 和 relibc , 暂时不设置这个标志位
  418. // if action.flags().contains(SigFlags::SA_FLAG_IMMUTABLE) {
  419. // return Err(SystemError::EINVAL);
  420. // }
  421. // 保存原有的 sigaction
  422. let old_act: Option<&mut Sigaction> = {
  423. if let Some(oa) = old_act {
  424. *(oa) = *action;
  425. Some(oa)
  426. } else {
  427. None
  428. }
  429. };
  430. // 清除所有的脏的sa_flags位(也就是清除那些未使用的)
  431. let act = {
  432. if let Some(ac) = act {
  433. *ac.flags_mut() &= SigFlags::SA_ALL;
  434. Some(ac)
  435. } else {
  436. None
  437. }
  438. };
  439. if let Some(act) = old_act {
  440. *act.flags_mut() &= SigFlags::SA_ALL;
  441. }
  442. if let Some(ac) = act {
  443. // 将act.sa_mask的SIGKILL SIGSTOP的屏蔽清除
  444. ac.mask_mut()
  445. .remove(<Signal as Into<SigSet>>::into(Signal::SIGKILL) | Signal::SIGSTOP.into());
  446. // 将新的sigaction拷贝到进程的action中
  447. *action = *ac;
  448. /*
  449. * 根据POSIX 3.3.1.3规定:
  450. * 1.不管一个信号是否被阻塞,只要将其设置SIG_IGN,如果当前已经存在了正在pending的信号,那么就把这个信号忽略。
  451. *
  452. * 2.不管一个信号是否被阻塞,只要将其设置SIG_DFL,如果当前已经存在了正在pending的信号,
  453. 并且对这个信号的默认处理方式是忽略它,那么就会把pending的信号忽略。
  454. */
  455. if action.is_ignore() {
  456. let mut mask: SigSet = SigSet::from_bits_truncate(0);
  457. mask.insert(sig.into());
  458. pcb.sig_info_mut().sig_pending_mut().flush_by_mask(&mask);
  459. // todo: 当有了多个线程后,在这里进行操作,把每个线程的sigqueue都进行刷新
  460. }
  461. }
  462. return Ok(());
  463. }
  464. /// https://code.dragonos.org.cn/xref/linux-6.6.21/include/uapi/asm-generic/signal-defs.h#72
  465. /// 对应SIG_BLOCK,SIG_UNBLOCK,SIG_SETMASK
  466. #[derive(Debug, Clone, Copy, PartialEq, Eq)]
  467. pub enum SigHow {
  468. Block = 0,
  469. Unblock = 1,
  470. SetMask = 2,
  471. }
  472. impl TryFrom<i32> for SigHow {
  473. type Error = SystemError;
  474. fn try_from(value: i32) -> Result<Self, Self::Error> {
  475. match value {
  476. 0 => Ok(SigHow::Block),
  477. 1 => Ok(SigHow::Unblock),
  478. 2 => Ok(SigHow::SetMask),
  479. _ => Err(SystemError::EINVAL),
  480. }
  481. }
  482. }
  483. fn __set_task_blocked(pcb: &Arc<ProcessControlBlock>, new_set: &SigSet) {
  484. //todo 还有一个对线程组是否为空的判断,进程组、线程组实现之后,需要更改这里。
  485. if pcb.has_pending_signal() {
  486. let mut newblocked = *new_set;
  487. let guard = pcb.sig_info_irqsave();
  488. newblocked.remove(*guard.sig_blocked());
  489. drop(guard);
  490. // 从主线程开始去遍历
  491. if let Some(group_leader) = pcb.threads_read_irqsave().group_leader() {
  492. retarget_shared_pending(group_leader, newblocked);
  493. }
  494. }
  495. *pcb.sig_info_mut().sig_block_mut() = *new_set;
  496. pcb.recalc_sigpending(None);
  497. }
  498. fn __set_current_blocked(new_set: &SigSet) {
  499. let pcb = ProcessManager::current_pcb();
  500. /*
  501. 如果当前pcb的sig_blocked和新的相等,那么就不用改变它。
  502. 请注意,一个进程的sig_blocked字段不能被其他进程修改!
  503. */
  504. if pcb.sig_info_irqsave().sig_blocked().eq(new_set) {
  505. return;
  506. }
  507. let guard: SpinLockGuard<'_, SignalStruct> = pcb.sig_struct_irqsave();
  508. __set_task_blocked(&pcb, new_set);
  509. drop(guard);
  510. }
  511. fn retarget_shared_pending(pcb: Arc<ProcessControlBlock>, which: SigSet) {
  512. let retarget = pcb.sig_info_irqsave().sig_shared_pending().signal();
  513. retarget.intersects(which);
  514. if retarget.is_empty() {
  515. return;
  516. }
  517. // 对于线程组中的每一个线程都要执行的函数
  518. let thread_handling_function = |pcb: Arc<ProcessControlBlock>, retarget: &SigSet| {
  519. if retarget.is_empty() {
  520. return;
  521. }
  522. if pcb.flags().contains(ProcessFlags::EXITING) {
  523. return;
  524. }
  525. let blocked = pcb.sig_info_irqsave().sig_shared_pending().signal();
  526. if retarget.difference(blocked).is_empty() {
  527. return;
  528. }
  529. retarget.intersects(blocked);
  530. if !pcb.has_pending_signal() {
  531. let guard = pcb.sig_struct_irqsave();
  532. signal_wake_up(pcb.clone(), guard, false);
  533. }
  534. // 之前的对retarget的判断移动到最前面,因为对于当前线程的线程的处理已经结束,对于后面的线程在一开始判断retarget为空即可结束处理
  535. // debug!("handle done");
  536. };
  537. // 暴力遍历每一个线程,找到相同的tgid
  538. let tgid = pcb.tgid();
  539. for &pid in pcb.children_read_irqsave().iter() {
  540. if let Some(child) = ProcessManager::find(pid) {
  541. if child.tgid() == tgid {
  542. thread_handling_function(child, &retarget);
  543. }
  544. }
  545. }
  546. // debug!("retarget_shared_pending done!");
  547. }
  548. /// 设置当前进程的屏蔽信号 (sig_block)
  549. ///
  550. /// ## 参数
  551. ///
  552. /// - `new_set` 新的屏蔽信号bitmap的值
  553. pub fn set_current_blocked(new_set: &mut SigSet) {
  554. let to_remove: SigSet =
  555. <Signal as Into<SigSet>>::into(Signal::SIGKILL) | Signal::SIGSTOP.into();
  556. new_set.remove(to_remove);
  557. __set_current_blocked(new_set);
  558. }
  559. /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/signal.c?fi=set_user_sigmask#set_user_sigmask
  560. /// 功能与set_current_blocked相同,多一步保存当前的sig_blocked到saved_sigmask
  561. /// 由于这之中设置了saved_sigmask,因此从系统调用返回之前需要恢复saved_sigmask
  562. pub fn set_user_sigmask(new_set: &mut SigSet) {
  563. let pcb = ProcessManager::current_pcb();
  564. let mut guard = pcb.sig_info_mut();
  565. let oset = *guard.sig_blocked();
  566. let flags = pcb.flags();
  567. flags.set(ProcessFlags::RESTORE_SIG_MASK, true);
  568. let saved_sigmask = guard.saved_sigmask_mut();
  569. *saved_sigmask = oset;
  570. drop(guard);
  571. set_current_blocked(new_set);
  572. }
  573. /// 设置当前进程的屏蔽信号 (sig_block)
  574. ///
  575. /// ## 参数
  576. ///
  577. /// - `how` 设置方式
  578. /// - `new_set` 新的屏蔽信号bitmap的值
  579. pub fn set_sigprocmask(how: SigHow, set: SigSet) -> Result<SigSet, SystemError> {
  580. let pcb: Arc<ProcessControlBlock> = ProcessManager::current_pcb();
  581. let guard = pcb.sig_info_irqsave();
  582. let oset = *guard.sig_blocked();
  583. let mut res_set = oset;
  584. drop(guard);
  585. match how {
  586. SigHow::Block => {
  587. // debug!("SIG_BLOCK\tGoing to insert is: {}", set.bits());
  588. res_set.insert(set);
  589. }
  590. SigHow::Unblock => {
  591. res_set.remove(set);
  592. }
  593. SigHow::SetMask => {
  594. // debug!("SIG_SETMASK\tGoing to set is: {}", set.bits());
  595. res_set = set;
  596. }
  597. }
  598. __set_current_blocked(&res_set);
  599. Ok(oset)
  600. }
  601. #[derive(Debug)]
  602. pub struct RestartBlock {
  603. pub data: RestartBlockData,
  604. pub restart_fn: &'static dyn RestartFn,
  605. }
  606. impl RestartBlock {
  607. pub fn new(restart_fn: &'static dyn RestartFn, data: RestartBlockData) -> Self {
  608. Self { data, restart_fn }
  609. }
  610. }
  611. pub trait RestartFn: Debug + Sync + Send + 'static {
  612. fn call(&self, data: &mut RestartBlockData) -> Result<usize, SystemError>;
  613. }
  614. #[derive(Debug, Clone)]
  615. pub enum RestartBlockData {
  616. Poll(PollRestartBlockData),
  617. // todo: nanosleep
  618. Nanosleep(),
  619. // todo: futex_wait
  620. FutexWait(),
  621. }
  622. impl RestartBlockData {
  623. pub fn new_poll(pollfd_ptr: VirtAddr, nfds: u32, timeout_instant: Option<Instant>) -> Self {
  624. Self::Poll(PollRestartBlockData {
  625. pollfd_ptr,
  626. nfds,
  627. timeout_instant,
  628. })
  629. }
  630. }
  631. #[derive(Debug, Clone)]
  632. pub struct PollRestartBlockData {
  633. pub pollfd_ptr: VirtAddr,
  634. pub nfds: u32,
  635. pub timeout_instant: Option<Instant>,
  636. }