WIP: Signal handling
This commit is contained in:
+1
-1
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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))?;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user