support killing signal to process group

This commit is contained in:
Jianfeng Jiang 2023-03-30 05:38:36 -04:00 committed by Tate, Hongliang Tian
parent 32f3f5c300
commit 0b15be894b
4 changed files with 42 additions and 40 deletions

View File

@ -9,6 +9,7 @@ use self::signal::constants::SIGCHLD;
use self::signal::sig_disposition::SigDispositions; use self::signal::sig_disposition::SigDispositions;
use self::signal::sig_queues::SigQueues; use self::signal::sig_queues::SigQueues;
use self::signal::signals::kernel::KernelSignal; use self::signal::signals::kernel::KernelSignal;
use self::signal::signals::Signal;
use self::status::ProcessStatus; use self::status::ProcessStatus;
use crate::fs::file_table::FileTable; use crate::fs::file_table::FileTable;
use crate::fs::fs_resolver::FsResolver; use crate::fs::fs_resolver::FsResolver;
@ -379,6 +380,12 @@ impl Process {
pub fn sig_queues(&self) -> &Mutex<SigQueues> { pub fn sig_queues(&self) -> &Mutex<SigQueues> {
&self.sig_queues &self.sig_queues
} }
pub fn enqueue_signal(&self, signal: Box<dyn Signal>) {
if !self.status().lock().is_zombie() {
self.sig_queues.lock().enqueue(signal);
}
}
} }
/// Get the init process /// Get the init process

View File

@ -1,4 +1,8 @@
use super::{process_table, signal::signals::kernel::KernelSignal, Pgid, Pid, Process}; use super::{
process_table,
signal::signals::{kernel::KernelSignal, user::UserSignal},
Pgid, Pid, Process,
};
use crate::prelude::*; use crate::prelude::*;
pub struct ProcessGroup { pub struct ProcessGroup {
@ -76,10 +80,14 @@ impl ProcessGroup {
/// send kernel signal to all processes in the group /// send kernel signal to all processes in the group
pub fn kernel_signal(&self, signal: KernelSignal) { pub fn kernel_signal(&self, signal: KernelSignal) {
for (_, process) in &self.inner.lock().processes { for (_, process) in &self.inner.lock().processes {
process process.enqueue_signal(Box::new(signal.clone()));
.sig_queues() }
.lock() }
.enqueue(Box::new(signal.clone()));
/// send user signal to all processes in the group
pub fn user_signal(&self, signal: UserSignal) {
for (_, process) in &self.inner.lock().processes {
process.enqueue_signal(Box::new(signal.clone()));
} }
} }
} }

View File

@ -85,8 +85,6 @@ pub fn handle_pending_signal(context: &mut CpuContext) -> Result<()> {
let mut status = current_thread.status().lock(); let mut status = current_thread.status().lock();
if status.is_running() { if status.is_running() {
status.set_stopped(); status.set_stopped();
} else {
panic!("Try to suspend a not running process.")
} }
drop(status); drop(status);
} }
@ -94,8 +92,6 @@ pub fn handle_pending_signal(context: &mut CpuContext) -> Result<()> {
let mut status = current_thread.status().lock(); let mut status = current_thread.status().lock();
if status.is_stopped() { if status.is_stopped() {
status.set_running(); status.set_running();
} else {
panic!("Try to continue a not suspended process.")
} }
drop(status); drop(status);
} }

View File

@ -1,7 +1,7 @@
use crate::{log_syscall_entry, prelude::*}; use crate::{log_syscall_entry, prelude::*};
use crate::process::process_table;
use crate::process::signal::signals::user::{UserSignal, UserSignalKind}; use crate::process::signal::signals::user::{UserSignal, UserSignalKind};
use crate::process::{process_table, Process};
use crate::{ use crate::{
process::{process_filter::ProcessFilter, signal::sig_num::SigNum}, process::{process_filter::ProcessFilter, signal::sig_num::SigNum},
syscall::SYS_KILL, syscall::SYS_KILL,
@ -21,41 +21,32 @@ pub fn sys_kill(process_filter: u64, sig_num: u64) -> Result<SyscallReturn> {
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }
pub fn do_sys_kill(process_filter: ProcessFilter, sig_num: SigNum) -> Result<()> { pub fn do_sys_kill(filter: ProcessFilter, sig_num: SigNum) -> Result<()> {
let current = current!(); let current = current!();
let pid = current.pid(); let pid = current.pid();
// FIXME: use the correct uid // FIXME: use the correct uid
let uid = 0; let uid = 0;
let processes = get_processes(&process_filter)?; let signal = UserSignal::new(sig_num, UserSignalKind::Kill, pid, uid);
for process in processes.iter() { match filter {
if process.status().lock().is_zombie() { ProcessFilter::Any => {
continue; for process in process_table::get_all_processes() {
process.enqueue_signal(Box::new(signal.clone()));
}
}
ProcessFilter::WithPid(pid) => {
if let Some(process) = process_table::pid_to_process(pid) {
process.enqueue_signal(Box::new(signal));
} else {
return_errno_with_message!(Errno::ESRCH, "No such process in process table");
}
}
ProcessFilter::WithPgid(pgid) => {
if let Some(process_group) = process_table::pgid_to_process_group(pgid) {
process_group.user_signal(signal);
} else {
return_errno_with_message!(Errno::ESRCH, "No such process group in process table");
}
} }
let signal = Box::new(UserSignal::new(sig_num, UserSignalKind::Kill, pid, uid));
let sig_queues = process.sig_queues();
sig_queues.lock().enqueue(signal);
} }
Ok(()) Ok(())
} }
fn get_processes(filter: &ProcessFilter) -> Result<Vec<Arc<Process>>> {
let processes = match filter {
ProcessFilter::Any => {
let mut processes = process_table::get_all_processes();
processes.retain(|process| process.pid() != 0);
processes
}
ProcessFilter::WithPid(pid) => {
let process = process_table::pid_to_process(*pid);
match process {
None => {
return_errno_with_message!(Errno::ESRCH, "No such process in process table")
}
Some(process) => vec![process],
}
}
ProcessFilter::WithPgid(_) => todo!(),
};
Ok(processes)
}