From 07262fd86652bd15724c335b4a9b9d85e3485b78 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 23 Jul 2017 15:55:47 -0600 Subject: [PATCH] Implement sending signals to process groups. Modify max context value to fit inside of isize --- src/context/mod.rs | 2 +- src/syscall/process.rs | 83 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index f0cd312c..f0e428c1 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -34,7 +34,7 @@ pub mod memory; pub mod timeout; /// Limit on number of contexts -pub const CONTEXT_MAX_CONTEXTS: usize = usize::max_value() - 1; +pub const CONTEXT_MAX_CONTEXTS: usize = (isize::max_value() as usize) - 1; /// Maximum context files pub const CONTEXT_MAX_FILES: usize = 65536; diff --git a/src/syscall/process.rs b/src/syscall/process.rs index aed80e3e..aceeaaaa 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -1013,25 +1013,88 @@ pub fn getppid() -> Result { } pub fn kill(pid: ContextId, sig: usize) -> Result { - let (ruid, euid) = { + println!("Kill {} {:X}", pid.into() as isize, sig); + + let (ruid, euid, current_pgid) = { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - (context.ruid, context.euid) + (context.ruid, context.euid, context.pgid) }; if sig > 0 && sig <= 0x7F { let contexts = context::contexts(); - let context_lock = contexts.get(pid).ok_or(Error::new(ESRCH))?; - let mut context = context_lock.write(); - if euid == 0 - || euid == context.ruid - || ruid == context.ruid - { - context.pending.push_back(sig as u8); - Ok(0) + + let mut found = 0; + let mut sent = 0; + + let send = |context: &mut context::Context| -> bool { + if euid == 0 + || euid == context.ruid + || ruid == context.ruid + { + println!("Send {:X} to {}", sig, context.id.into()); + context.pending.push_back(sig as u8); + true + } else { + false + } + }; + + if pid.into() > 0 { + // Send to a single process + if let Some(context_lock) = contexts.get(pid) { + let mut context = context_lock.write(); + + found += 1; + if send(&mut context) { + sent += 1; + } + } + } else if pid.into() as isize == -1 { + // Send to every process with permission, except for init + for (_id, context_lock) in contexts.iter() { + let mut context = context_lock.write(); + + if context.id.into() > 2 { + found += 1; + + if send(&mut context) { + sent += 1; + } + } + } } else { + let pgid = if pid.into() == 0 { + current_pgid + } else { + ContextId::from(-(pid.into() as isize) as usize) + }; + + println!("pgid {}", pgid.into()); + + // Send to every process in the process group whose ID + for (_id, context_lock) in contexts.iter() { + let mut context = context_lock.write(); + + if context.pgid == pgid { + found += 1; + + if send(&mut context) { + sent += 1; + } + } + } + } + + println!("Found {}, sent to {}", found, sent); + + if found == 0 { + Err(Error::new(ESRCH)) + } else if sent == 0 { Err(Error::new(EPERM)) + } else { + Ok(0) } } else { Err(Error::new(EINVAL))