diff --git a/src/services/libs/jinux-std/src/process/mod.rs b/src/services/libs/jinux-std/src/process/mod.rs index 755cdff43..49a2538fb 100644 --- a/src/services/libs/jinux-std/src/process/mod.rs +++ b/src/services/libs/jinux-std/src/process/mod.rs @@ -9,6 +9,7 @@ use self::signal::constants::SIGCHLD; use self::signal::sig_disposition::SigDispositions; use self::signal::sig_queues::SigQueues; use self::signal::signals::kernel::KernelSignal; +use self::signal::signals::Signal; use self::status::ProcessStatus; use crate::fs::file_table::FileTable; use crate::fs::fs_resolver::FsResolver; @@ -379,6 +380,12 @@ impl Process { pub fn sig_queues(&self) -> &Mutex { &self.sig_queues } + + pub fn enqueue_signal(&self, signal: Box) { + if !self.status().lock().is_zombie() { + self.sig_queues.lock().enqueue(signal); + } + } } /// Get the init process diff --git a/src/services/libs/jinux-std/src/process/process_group.rs b/src/services/libs/jinux-std/src/process/process_group.rs index cb9676b34..f469e2e3c 100644 --- a/src/services/libs/jinux-std/src/process/process_group.rs +++ b/src/services/libs/jinux-std/src/process/process_group.rs @@ -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::*; pub struct ProcessGroup { @@ -76,10 +80,14 @@ impl ProcessGroup { /// send kernel signal to all processes in the group pub fn kernel_signal(&self, signal: KernelSignal) { for (_, process) in &self.inner.lock().processes { - process - .sig_queues() - .lock() - .enqueue(Box::new(signal.clone())); + process.enqueue_signal(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())); } } } diff --git a/src/services/libs/jinux-std/src/process/signal/mod.rs b/src/services/libs/jinux-std/src/process/signal/mod.rs index 3c2913e44..caa739bfa 100644 --- a/src/services/libs/jinux-std/src/process/signal/mod.rs +++ b/src/services/libs/jinux-std/src/process/signal/mod.rs @@ -85,8 +85,6 @@ pub fn handle_pending_signal(context: &mut CpuContext) -> Result<()> { let mut status = current_thread.status().lock(); if status.is_running() { status.set_stopped(); - } else { - panic!("Try to suspend a not running process.") } drop(status); } @@ -94,8 +92,6 @@ pub fn handle_pending_signal(context: &mut CpuContext) -> Result<()> { let mut status = current_thread.status().lock(); if status.is_stopped() { status.set_running(); - } else { - panic!("Try to continue a not suspended process.") } drop(status); } diff --git a/src/services/libs/jinux-std/src/syscall/kill.rs b/src/services/libs/jinux-std/src/syscall/kill.rs index e5b234bc1..a175894be 100644 --- a/src/services/libs/jinux-std/src/syscall/kill.rs +++ b/src/services/libs/jinux-std/src/syscall/kill.rs @@ -1,7 +1,7 @@ use crate::{log_syscall_entry, prelude::*}; +use crate::process::process_table; use crate::process::signal::signals::user::{UserSignal, UserSignalKind}; -use crate::process::{process_table, Process}; use crate::{ process::{process_filter::ProcessFilter, signal::sig_num::SigNum}, syscall::SYS_KILL, @@ -21,41 +21,32 @@ pub fn sys_kill(process_filter: u64, sig_num: u64) -> Result { 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 pid = current.pid(); // FIXME: use the correct uid let uid = 0; - let processes = get_processes(&process_filter)?; - for process in processes.iter() { - if process.status().lock().is_zombie() { - continue; + let signal = UserSignal::new(sig_num, UserSignalKind::Kill, pid, uid); + match filter { + ProcessFilter::Any => { + 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(()) } - -fn get_processes(filter: &ProcessFilter) -> Result>> { - 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) -}