diff --git a/src/context/context.rs b/src/context/context.rs index 8fc4281..6ade469 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -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, /// 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, diff --git a/src/context/switch.rs b/src/context/switch.rs index 859d573..3395660 100644 --- a/src/context/switch.rs +++ b/src/context/switch.rs @@ -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 { diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 451e6a3..74816cc 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -956,7 +956,7 @@ pub fn getppid() -> Result { } pub fn kill(pid: ContextId, sig: usize) -> Result { - 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 { || 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 { 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 { } } - println!("Found {}, sent to {}", found, sent); - if found == 0 { Err(Error::new(ESRCH)) } else if sent == 0 {