Add support for stop/cont signals
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user