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

* 实现SIGINT终止信号传递

* 添加test_sigint测试程序
This commit is contained in:
MemoryShore 2024-10-09 19:02:14 +08:00 committed by GitHub
parent 52dc4c3ee8
commit a8753f8fff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 103 additions and 10 deletions

View File

@ -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);
}

View File

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

View File

@ -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;

View File

@ -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
user/apps/test_sigint/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test_sigint

View File

@ -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:

View File

@ -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;
}

View File

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

View File

@ -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"]
}