mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
support killing signal to process group
This commit is contained in:
parent
32f3f5c300
commit
0b15be894b
@ -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<SigQueues> {
|
||||
&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
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<SyscallReturn> {
|
||||
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<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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user