From a8753f8fffb992e4d3bbd21eda431081b395af6b Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Wed, 9 Oct 2024 19:02:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(tty):=20=E5=AE=9E=E7=8E=B0=E5=8F=91?= =?UTF-8?q?=E9=80=81SIGINT=E7=BB=88=E6=AD=A2=E4=BF=A1=E5=8F=B7=20(#952)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 实现SIGINT终止信号传递 * 添加test_sigint测试程序 --- kernel/src/driver/tty/tty_job_control.rs | 8 +++---- kernel/src/driver/tty/tty_ldisc/ntty.rs | 1 - kernel/src/process/fork.rs | 3 +++ kernel/src/process/mod.rs | 25 +++++++++++++++++--- user/apps/test_sigint/.gitignore | 1 + user/apps/test_sigint/Makefile | 20 ++++++++++++++++ user/apps/test_sigint/main.c | 29 ++++++++++++++++++++++++ user/dadk/config/nova_shell-0.1.0.dadk | 2 +- user/dadk/config/test_sigint-0.1.0.dadk | 24 ++++++++++++++++++++ 9 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 user/apps/test_sigint/.gitignore create mode 100644 user/apps/test_sigint/Makefile create mode 100644 user/apps/test_sigint/main.c create mode 100644 user/dadk/config/test_sigint-0.1.0.dadk diff --git a/kernel/src/driver/tty/tty_job_control.rs b/kernel/src/driver/tty/tty_job_control.rs index 653b3777..4cc078cc 100644 --- a/kernel/src/driver/tty/tty_job_control.rs +++ b/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(¤t.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); } diff --git a/kernel/src/driver/tty/tty_ldisc/ntty.rs b/kernel/src/driver/tty/tty_ldisc/ntty.rs index 8f2ed695..c26b3a29 100644 --- a/kernel/src/driver/tty/tty_ldisc/ntty.rs +++ b/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) { // 重置 diff --git a/kernel/src/process/fork.rs b/kernel/src/process/fork.rs index 2ad49fe9..f750e4c2 100644 --- a/kernel/src/process/fork.rs +++ b/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; diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index f48d4491..fa35a988 100644 --- a/kernel/src/process/mod.rs +++ b/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>, @@ -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) { - self.tty = Some(tty); + pub fn set_tty(&mut self, tty: Option>) { + self.tty = tty; } /// 从 pcb 的 siginfo中取出下一个要处理的信号,先处理线程信号,再处理进程信号 diff --git a/user/apps/test_sigint/.gitignore b/user/apps/test_sigint/.gitignore new file mode 100644 index 00000000..9f87ac52 --- /dev/null +++ b/user/apps/test_sigint/.gitignore @@ -0,0 +1 @@ +test_sigint diff --git a/user/apps/test_sigint/Makefile b/user/apps/test_sigint/Makefile new file mode 100644 index 00000000..d58e499f --- /dev/null +++ b/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: diff --git a/user/apps/test_sigint/main.c b/user/apps/test_sigint/main.c new file mode 100644 index 00000000..10a9d5c5 --- /dev/null +++ b/user/apps/test_sigint/main.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +// 信号处理函数 +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; +} diff --git a/user/dadk/config/nova_shell-0.1.0.dadk b/user/dadk/config/nova_shell-0.1.0.dadk index 5b5b79b5..0e9c456c 100644 --- a/user/dadk/config/nova_shell-0.1.0.dadk +++ b/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" } } }, diff --git a/user/dadk/config/test_sigint-0.1.0.dadk b/user/dadk/config/test_sigint-0.1.0.dadk new file mode 100644 index 00000000..59b63f84 --- /dev/null +++ b/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"] +}