mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 13:26: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_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
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user