Browse Source

feat(tty): 实现发送SIGINT终止信号 (#952)

* 实现SIGINT终止信号传递

* 添加test_sigint测试程序
MemoryShore 5 months ago
parent
commit
a8753f8fff

+ 3 - 5
kernel/src/driver/tty/tty_job_control.rs

@@ -22,15 +22,13 @@ impl TtyJobCtrlManager {
         let mut ctrl = core.contorl_info_irqsave();
         let pcb = ProcessManager::current_pcb();
 
-        // todo 目前将pgid设置为pid
-        ctrl.pgid = Some(pcb.pid());
-        ctrl.session = Some(pcb.pid());
+        ctrl.session = Some(pcb.basic().sid());
 
         assert!(pcb.sig_info_irqsave().tty().is_none());
 
         let mut singal = pcb.sig_info_mut();
         drop(ctrl);
-        singal.set_tty(tty);
+        singal.set_tty(Some(tty.clone()));
     }
 
     /// ### 检查tty
@@ -99,7 +97,7 @@ impl TtyJobCtrlManager {
                 if current.sig_info_irqsave().tty().is_none()
                     || !Arc::ptr_eq(&current.sig_info_irqsave().tty().clone().unwrap(), &tty)
                     || ctrl.session.is_none()
-                    || ctrl.session.unwrap() != current.pid()
+                    || ctrl.session.unwrap() != current.basic().sid()
                 {
                     return Err(SystemError::ENOTTY);
                 }

+ 0 - 1
kernel/src/driver/tty/tty_ldisc/ntty.rs

@@ -792,7 +792,6 @@ impl NTtyData {
         }
 
         ctrl_info.pgid = None;
-        ctrl_info.session = None;
 
         if !termios.local_mode.contains(LocalMode::NOFLSH) {
             // 重置

+ 3 - 0
kernel/src/process/fork.rs

@@ -166,6 +166,9 @@ impl ProcessManager {
 
         let pcb = ProcessControlBlock::new(name, new_kstack);
 
+        pcb.sig_info_mut()
+            .set_tty(current_pcb.sig_info_irqsave().tty());
+
         let mut args = KernelCloneArgs::new();
         args.flags = clone_flags;
         args.exit_signal = Signal::SIGCHLD;

+ 22 - 3
kernel/src/process/mod.rs

@@ -422,6 +422,17 @@ impl ProcessManager {
         }
         drop(thread);
         unsafe { pcb.basic_mut().set_user_vm(None) };
+
+        // TODO 由于未实现进程组,tty记录的前台进程组等于当前进程,故退出前要置空
+        // 后续相关逻辑需要在SYS_EXIT_GROUP系统调用中实现
+        pcb.sig_info_irqsave()
+            .tty()
+            .unwrap()
+            .core()
+            .contorl_info_irqsave()
+            .pgid = None;
+        pcb.sig_info_mut().set_tty(None);
+
         drop(pcb);
         ProcessManager::exit_notify();
         // unsafe { CurrentIrqArch::interrupt_enable() };
@@ -704,7 +715,7 @@ impl ProcessControlBlock {
             (Self::generate_pid(), ppid, cwd, cred)
         };
 
-        let basic_info = ProcessBasicInfo::new(Pid(0), ppid, name, cwd, None);
+        let basic_info = ProcessBasicInfo::new(Pid(0), ppid, Pid(0), name, cwd, None);
         let preempt_count = AtomicUsize::new(0);
         let flags = unsafe { LockFreeFlags::new(ProcessFlags::empty()) };
 
@@ -1069,6 +1080,8 @@ pub struct ProcessBasicInfo {
     pgid: Pid,
     /// 当前进程的父进程的pid
     ppid: Pid,
+    /// 当前进程所属会话id
+    sid: Pid,
     /// 进程的名字
     name: String,
 
@@ -1087,6 +1100,7 @@ impl ProcessBasicInfo {
     pub fn new(
         pgid: Pid,
         ppid: Pid,
+        sid: Pid,
         name: String,
         cwd: String,
         user_vm: Option<Arc<AddressSpace>>,
@@ -1095,6 +1109,7 @@ impl ProcessBasicInfo {
         return RwLock::new(Self {
             pgid,
             ppid,
+            sid,
             name,
             cwd,
             user_vm,
@@ -1110,6 +1125,10 @@ impl ProcessBasicInfo {
         return self.ppid;
     }
 
+    pub fn sid(&self) -> Pid {
+        return self.sid;
+    }
+
     pub fn name(&self) -> &str {
         return &self.name;
     }
@@ -1516,8 +1535,8 @@ impl ProcessSignalInfo {
         self.tty.clone()
     }
 
-    pub fn set_tty(&mut self, tty: Arc<TtyCore>) {
-        self.tty = Some(tty);
+    pub fn set_tty(&mut self, tty: Option<Arc<TtyCore>>) {
+        self.tty = tty;
     }
 
     /// 从 pcb 的 siginfo中取出下一个要处理的信号,先处理线程信号,再处理进程信号

+ 1 - 0
user/apps/test_sigint/.gitignore

@@ -0,0 +1 @@
+test_sigint

+ 20 - 0
user/apps/test_sigint/Makefile

@@ -0,0 +1,20 @@
+ifeq ($(ARCH), x86_64)
+	CROSS_COMPILE=x86_64-linux-musl-
+else ifeq ($(ARCH), riscv64)
+	CROSS_COMPILE=riscv64-linux-musl-
+endif
+
+CC=$(CROSS_COMPILE)gcc
+
+.PHONY: all
+all: main.c
+	$(CC) -static -o test_sigint main.c
+
+.PHONY: install clean
+install: all
+	mv test_sigint $(DADK_CURRENT_BUILD_DIR)/test_sigint
+
+clean:
+	rm test_sigint *.o
+
+fmt:

+ 29 - 0
user/apps/test_sigint/main.c

@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+// 信号处理函数
+void handle_signal(int signal)
+{
+    if (signal == SIGINT)
+    {
+        printf("Caught SIGINT (Ctrl+C). Exiting gracefully...\n");
+        exit(0); // 终止程序
+    }
+}
+
+int main()
+{
+    // 注册信号处理函数
+    signal(SIGINT, handle_signal);
+
+    // 模拟一个长时间运行的进程
+    while (1)
+    {
+        printf("Running... Press Ctrl+C to stop.\n");
+        sleep(5);
+    }
+
+    return 0;
+}

+ 1 - 1
user/dadk/config/nova_shell-0.1.0.dadk

@@ -6,7 +6,7 @@
     "BuildFromSource": {
       "Git": {
         "url": "https://git.mirrors.dragonos.org.cn/DragonOS-Community/NovaShell.git",
-        "revision": "6c1ca14da7"
+        "revision": "b0dea7c16f"
       }
     }
   },

+ 24 - 0
user/dadk/config/test_sigint-0.1.0.dadk

@@ -0,0 +1,24 @@
+{
+  "name": "test_sigint",
+  "version": "0.1.0",
+  "description": "一个用来测试sigint信号传递的app",
+  "task_type": {
+    "BuildFromSource": {
+      "Local": {
+        "path": "apps/test_sigint"
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "make install"
+  },
+  "install": {
+    "in_dragonos_path": "/bin"
+  },
+  "clean": {
+    "clean_command": "make clean"
+  },
+  "envs": [],
+  "target_arch": ["x86_64"]
+}