WIP: Signal handling
This commit is contained in:
+14
-4
@@ -1,6 +1,7 @@
|
||||
use alloc::arc::Arc;
|
||||
use alloc::boxed::Box;
|
||||
use collections::{BTreeMap, Vec, VecDeque};
|
||||
use core::mem;
|
||||
use spin::Mutex;
|
||||
|
||||
use context::arch;
|
||||
@@ -8,7 +9,8 @@ use context::file::File;
|
||||
use context::memory::{Grant, Memory, SharedMemory, Tls};
|
||||
use device;
|
||||
use scheme::{SchemeNamespace, FileHandle};
|
||||
use syscall::data::Event;
|
||||
use syscall::data::{Event, SigAction};
|
||||
use syscall::flag::SIG_DFL;
|
||||
use sync::{WaitMap, WaitQueue};
|
||||
|
||||
/// Unique identifier for a context (i.e. `pid`).
|
||||
@@ -69,6 +71,8 @@ pub struct Context {
|
||||
pub heap: Option<SharedMemory>,
|
||||
/// User stack
|
||||
pub stack: Option<Memory>,
|
||||
/// User signal stack
|
||||
pub sigstack: Option<Memory>,
|
||||
/// User Thread local storage
|
||||
pub tls: Option<Tls>,
|
||||
/// User grants
|
||||
@@ -83,8 +87,8 @@ pub struct Context {
|
||||
pub env: Arc<Mutex<BTreeMap<Box<[u8]>, Arc<Mutex<Vec<u8>>>>>>,
|
||||
/// The open files in the scheme
|
||||
pub files: Arc<Mutex<Vec<Option<File>>>>,
|
||||
/// Singal handlers
|
||||
pub handlers: Arc<Mutex<BTreeMap<u8, usize>>>,
|
||||
/// Singal actions
|
||||
pub actions: Arc<Mutex<Vec<SigAction>>>,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
@@ -111,6 +115,7 @@ impl Context {
|
||||
image: Vec::new(),
|
||||
heap: None,
|
||||
stack: None,
|
||||
sigstack: None,
|
||||
tls: None,
|
||||
grants: Arc::new(Mutex::new(Vec::new())),
|
||||
name: Arc::new(Mutex::new(Vec::new())),
|
||||
@@ -118,7 +123,12 @@ impl Context {
|
||||
events: Arc::new(WaitQueue::new()),
|
||||
env: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
files: Arc::new(Mutex::new(Vec::new())),
|
||||
handlers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
actions: Arc::new(Mutex::new(vec![SigAction {
|
||||
sa_handler: unsafe { mem::transmute(SIG_DFL) },
|
||||
sa_mask: [0; 2],
|
||||
sa_flags: 0,
|
||||
sa_restorer: unsafe { mem::transmute(0usize) },
|
||||
}; 128])),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-7
@@ -1,9 +1,12 @@
|
||||
use core::mem;
|
||||
use core::sync::atomic::Ordering;
|
||||
use context::{arch, contexts, Context, Status, CONTEXT_ID};
|
||||
use interrupt::irq::PIT_TICKS;
|
||||
use start::usermode;
|
||||
use syscall::flag::{SIG_DFL, SIG_IGN};
|
||||
|
||||
use gdt;
|
||||
use interrupt;
|
||||
use interrupt::irq::PIT_TICKS;
|
||||
use syscall;
|
||||
use time;
|
||||
|
||||
@@ -118,19 +121,35 @@ pub unsafe fn switch() -> bool {
|
||||
}
|
||||
|
||||
extern "C" fn signal_handler(sig: usize) {
|
||||
let handler = {
|
||||
let action = {
|
||||
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)
|
||||
let actions = context.actions.lock();
|
||||
actions[sig]
|
||||
};
|
||||
|
||||
println!("Signal handler: {}, {:X}", sig, handler);
|
||||
println!("Signal handler: {:X}, {:?}", sig, action);
|
||||
|
||||
if handler == 0 {
|
||||
let handler = action.sa_handler as usize;
|
||||
let restorer = action.sa_restorer as usize;
|
||||
if handler == SIG_DFL {
|
||||
println!("Exit {:X}", sig);
|
||||
syscall::exit(sig);
|
||||
} else if handler == SIG_IGN {
|
||||
println!("Ignore");
|
||||
} else {
|
||||
// TODO: Call handler
|
||||
println!("Call {:X}", handler);
|
||||
|
||||
unsafe {
|
||||
let mut sp = ::USER_SIGSTACK_OFFSET + ::USER_SIGSTACK_SIZE - 256;
|
||||
|
||||
sp = (sp / 16) * 16;
|
||||
|
||||
sp -= mem::size_of::<usize>();
|
||||
*(sp as *mut usize) = restorer;
|
||||
|
||||
usermode(handler, sp, sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user