WIP: Signal handling

This commit is contained in:
Jeremy Soller
2017-07-05 21:45:53 -06:00
parent a4c3afb446
commit 0e8e1b5c4e
6 changed files with 53 additions and 9 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ alloc_kernel = { path = "alloc_kernel" }
bitflags = "0.7"
spin = "0.4"
raw-cpuid = { git = "https://github.com/gz/rust-cpuid", branch = "master" }
redox_syscall = "0.1"
redox_syscall = { version = "0.1", path = "../syscall" }
[dependencies.goblin]
version = "0.0.10"
+5 -2
View File
@@ -82,7 +82,9 @@ pub struct Context {
/// The process environment
pub env: Arc<Mutex<BTreeMap<Box<[u8]>, Arc<Mutex<Vec<u8>>>>>>,
/// The open files in the scheme
pub files: Arc<Mutex<Vec<Option<File>>>>
pub files: Arc<Mutex<Vec<Option<File>>>>,
/// Singal handlers
pub handlers: Arc<Mutex<BTreeMap<u8, usize>>>,
}
impl Context {
@@ -115,7 +117,8 @@ impl Context {
cwd: Arc::new(Mutex::new(Vec::new())),
events: Arc::new(WaitQueue::new()),
env: Arc::new(Mutex::new(BTreeMap::new())),
files: Arc::new(Mutex::new(Vec::new()))
files: Arc::new(Mutex::new(Vec::new())),
handlers: Arc::new(Mutex::new(BTreeMap::new())),
}
}
+16 -4
View File
@@ -109,7 +109,6 @@ pub unsafe fn switch() -> bool {
arch::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst);
if let Some(sig) = to_sig {
println!("Handle {}", sig);
(&mut *to_ptr).arch.signal_stack(signal_handler, sig);
}
@@ -118,7 +117,20 @@ pub unsafe fn switch() -> bool {
true
}
extern "C" fn signal_handler(signal: usize) {
println!("Signal handler: {}", signal);
syscall::exit(signal);
extern "C" fn signal_handler(sig: usize) {
let handler = {
let contexts = contexts();
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
let context = context_lock.read();
let handlers = context.handlers.lock();
handlers.get(&(sig as u8)).map_or(0, |sig| *sig)
};
println!("Signal handler: {}, {:X}", sig, handler);
if handler == 0 {
syscall::exit(sig);
} else {
// TODO: Call handler
}
}
+1 -1
View File
@@ -214,7 +214,7 @@ impl Scheme for EnvScheme {
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
}
fn unlink(&self, path: &[u8], uid: u32, _gid: u32) -> Result<usize> {
fn unlink(&self, path: &[u8], _uid: u32, _gid: u32) -> Result<usize> {
let env_lock = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
+1
View File
@@ -80,6 +80,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
SYS_EXIT => exit((b & 0xFF) << 8),
SYS_KILL => kill(ContextId::from(b), c),
SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into),
SYS_SIGNAL => signal(b, c),
SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
SYS_IOPL => iopl(b, stack),
+29 -1
View File
@@ -18,7 +18,7 @@ use scheme::{self, FileHandle};
use syscall;
use syscall::data::Stat;
use syscall::error::*;
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, O_CLOEXEC, WNOHANG};
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, O_CLOEXEC, SIG_DFL, WNOHANG};
use syscall::validate::{validate_slice, validate_slice_mut};
pub fn brk(address: usize) -> Result<usize> {
@@ -83,6 +83,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
let cwd;
let env;
let files;
let handlers;
// Copy from old process
{
@@ -247,6 +248,12 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
} else {
files = Arc::new(Mutex::new(context.files.lock().clone()));
}
if flags & CLONE_SIGHAND == CLONE_SIGHAND {
handlers = context.handlers.clone();
} else {
handlers = Arc::new(Mutex::new(context.handlers.lock().clone()));
}
}
// If not cloning files, dup to get a new number from scheme
@@ -445,6 +452,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
context.env = env;
context.files = files;
context.handlers = handlers;
}
}
@@ -726,6 +735,8 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
let files = Arc::new(Mutex::new(context.files.lock().clone()));
context.files = files.clone();
context.handlers = Arc::new(Mutex::new(BTreeMap::new()));
let vfork = context.vfork;
context.vfork = false;
(vfork, context.ppid, files)
@@ -958,6 +969,23 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
}
}
pub fn signal(sig: usize, handler: usize) -> Result<usize> {
if sig > 0 && sig <= 0x7F {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let mut handlers = context.handlers.lock();
let previous = if handler == SIG_DFL {
handlers.remove(&(sig as u8))
} else {
handlers.insert(sig as u8, handler)
};
Ok(previous.unwrap_or(0))
} else {
Err(Error::new(EINVAL))
}
}
fn reap(pid: ContextId) -> Result<ContextId> {
// Spin until not running
let mut running = true;