Add support for stop/cont signals

This commit is contained in:
Jeremy Soller
2018-01-02 22:05:29 -07:00
parent 22aca69ac9
commit 7906f6891e
3 changed files with 37 additions and 10 deletions

View File

@@ -51,6 +51,8 @@ pub struct Context {
pub status: Status,
/// Context running or not
pub running: bool,
/// Context is stopped
pub stopped: bool,
/// CPU ID, if locked
pub cpu_id: Option<usize>,
/// Current system call
@@ -113,6 +115,7 @@ impl Context {
ens: SchemeNamespace::from(0),
status: Status::Blocked,
running: false,
stopped: false,
cpu_id: None,
syscall: None,
vfork: false,

View File

@@ -2,7 +2,7 @@ use core::mem;
use core::sync::atomic::Ordering;
use context::{arch, contexts, Context, Status, CONTEXT_ID};
use start::usermode;
use syscall::flag::{SIG_DFL, SIG_IGN};
use syscall::flag::{SIG_DFL, SIG_IGN, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU};
use gdt;
use interrupt;
@@ -163,10 +163,39 @@ extern "C" fn signal_handler(sig: usize) {
};
let handler = action.sa_handler as usize;
println!("Handler {:X}: {:X}", sig, handler);
println!("Handler {}: {:X}", sig, handler);
if handler == SIG_DFL {
println!("Exit {:X}", sig);
syscall::exit(sig);
match sig {
SIGCHLD => {
println!("SIGCHLD");
},
SIGCONT => {
println!("Continue");
let contexts = contexts();
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
let mut context = context_lock.write();
if context.stopped {
context.stopped = false;
context.unblock();
}
},
SIGSTOP | SIGTSTP | SIGTTIN | SIGTTOU => {
println!("Stop");
let contexts = contexts();
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
let mut context = context_lock.write();
if ! context.stopped {
context.stopped = true;
context.block();
}
},
_ => {
println!("Exit {}", sig);
syscall::exit(sig);
}
}
} else if handler == SIG_IGN {
println!("Ignore");
} else {

View File

@@ -956,7 +956,7 @@ pub fn getppid() -> Result<ContextId> {
}
pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
println!("Kill {} {:X}", pid.into() as isize, sig);
println!("Kill {} {}", pid.into() as isize, sig);
let (ruid, euid, current_pgid) = {
let contexts = context::contexts();
@@ -976,7 +976,6 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
|| euid == context.ruid
|| ruid == context.ruid
{
println!("Send {:X} to {}", sig, context.id.into());
context.pending.push_back(sig as u8);
true
} else {
@@ -1014,8 +1013,6 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
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();
@@ -1030,8 +1027,6 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
}
}
println!("Found {}, sent to {}", found, sent);
if found == 0 {
Err(Error::new(ESRCH))
} else if sent == 0 {