diff --git a/kernel/src/ipc/signal.rs b/kernel/src/ipc/signal.rs index f5304878d..b3d15cd0d 100644 --- a/kernel/src/ipc/signal.rs +++ b/kernel/src/ipc/signal.rs @@ -615,6 +615,24 @@ pub fn set_current_blocked(new_set: &mut SigSet) { __set_current_blocked(new_set); } +/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/signal.c?fi=set_user_sigmask#set_user_sigmask +/// 功能与set_current_blocked相同,多一步保存当前的sig_blocked到saved_sigmask +/// 由于这之中设置了saved_sigmask,因此从系统调用返回之前需要恢复saved_sigmask +pub fn set_user_sigmask(new_set: &mut SigSet) { + let pcb = ProcessManager::current_pcb(); + let mut guard = pcb.sig_info_mut(); + let oset = *guard.sig_blocked(); + + let flags = pcb.flags(); + flags.set(ProcessFlags::RESTORE_SIG_MASK, true); + + let saved_sigmask = guard.saved_sigmask_mut(); + *saved_sigmask = oset; + drop(guard); + + set_current_blocked(new_set); +} + /// 设置当前进程的屏蔽信号 (sig_block) /// /// ## 参数 diff --git a/kernel/src/net/event_poll/syscall.rs b/kernel/src/net/event_poll/syscall.rs index 6fd0dc941..bfd8dc762 100644 --- a/kernel/src/net/event_poll/syscall.rs +++ b/kernel/src/net/event_poll/syscall.rs @@ -3,7 +3,7 @@ use system_error::SystemError; use crate::{ arch::ipc::signal::SigSet, filesystem::vfs::file::FileMode, - ipc::signal::set_current_blocked, + ipc::signal::{restore_saved_sigmask, set_user_sigmask}, mm::VirtAddr, syscall::{ user_access::{UserBufferReader, UserBufferWriter}, @@ -96,13 +96,12 @@ impl Syscall { sigmask: &mut SigSet, ) -> Result { // 设置屏蔽的信号 - set_current_blocked(sigmask); + set_user_sigmask(sigmask); let wait_ret = Self::epoll_wait(epfd, epoll_event, max_events, timespec); if wait_ret.is_err() && *wait_ret.as_ref().unwrap_err() != SystemError::EINTR { - // TODO: 恢复信号? - // link:https://code.dragonos.org.cn/xref/linux-6.1.9/fs/eventpoll.c#2294 + restore_saved_sigmask(); } wait_ret } diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index ef52d6ceb..a87b4f91d 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -1596,6 +1596,7 @@ pub fn process_init() { pub struct ProcessSignalInfo { // 当前进程被屏蔽的信号 sig_blocked: SigSet, + // 暂存旧信号,用于恢复 saved_sigmask: SigSet, // sig_pending 中存储当前线程要处理的信号 sig_pending: SigPending,