Browse Source

添加set_user_sigmask (#1090)

火花 3 weeks ago
parent
commit
24b102b030
3 changed files with 22 additions and 4 deletions
  1. 18 0
      kernel/src/ipc/signal.rs
  2. 3 4
      kernel/src/net/event_poll/syscall.rs
  3. 1 0
      kernel/src/process/mod.rs

+ 18 - 0
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)
 ///
 /// ## 参数

+ 3 - 4
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<usize, SystemError> {
         // 设置屏蔽的信号
-        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
     }

+ 1 - 0
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,