Add support for WCONTINUED and WUNTRACED

Fix issues with SIGCONT
This commit is contained in:
Jeremy Soller
2018-01-03 22:34:50 -07:00
parent b6878760c7
commit 49d5c33928
6 changed files with 192 additions and 127 deletions

56
Cargo.lock generated
View File

@@ -34,9 +34,9 @@ name = "cargo_metadata"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -46,7 +46,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy_lints 0.0.177 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -60,10 +60,10 @@ dependencies = [
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -135,7 +135,7 @@ dependencies = [
"clippy 0.0.177 (registry+https://github.com/rust-lang/crates.io-index)",
"goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-cpuid 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.33",
"redox_syscall 0.1.35",
"spin 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"x86 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -147,7 +147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.34"
version = "0.2.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -168,7 +168,7 @@ name = "memchr"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -224,23 +224,23 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.1.33"
version = "0.1.35"
[[package]]
name = "regex"
version = "0.2.3"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.4.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -263,22 +263,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.25"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.25"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive_internals"
version = "0.18.1"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -287,13 +287,13 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.8"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -333,7 +333,7 @@ name = "toml"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -408,7 +408,7 @@ dependencies = [
"checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21"
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
"checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb"
"checksum linked_list_allocator 0.4.1 (git+https://github.com/redox-os/linked-list-allocator.git)" = "<none>"
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
@@ -420,15 +420,15 @@ dependencies = [
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum raw-cpuid 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13b844e4049605ff38fed943f5c7b2c691fad68d9d5bf074d2720554c4e48246"
"checksum raw-cpuid 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "779585861d55e586db9d6abe4352cd9466e09a3319342c417baf34b2740af74e"
"checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa"
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
"checksum scroll 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d916a75d18d4c559fa7312afe6f522fe5b63176e6591d02ed81017c22f8ea27"
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "386122ba68c214599c44587e0c0b411e8d90894503a95425b4f9508e4317901f"
"checksum serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "ec0bfa6c5784e7d110514448da0e1dbad41ea5514c3e68be755b23858b83a399"
"checksum serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "730fe9f29fe8db69a601837f416e46cba07792031ed6b27557a43e49d62d89ae"
"checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839"
"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526"
"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0"
"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5"
"checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb"
"checksum spin 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7e4deb3c2455c73779e6d3eebceae9599fc70957e54c69fe88f93aa48e62f432"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"

View File

@@ -30,6 +30,9 @@ pub mod file;
/// Memory struct - contains a set of pages for a context
pub mod memory;
/// Signal handling
pub mod signal;
/// Timeout handling
pub mod timeout;

96
src/context/signal.rs Normal file
View File

@@ -0,0 +1,96 @@
use alloc::arc::Arc;
use core::mem;
use context::{contexts, Status};
use start::usermode;
use syscall;
use syscall::flag::{SIG_DFL, SIG_IGN, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU};
pub extern "C" fn signal_handler(sig: usize) {
let (action, restorer) = {
let contexts = contexts();
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
let context = context_lock.read();
let actions = context.actions.lock();
actions[sig]
};
let handler = action.sa_handler as usize;
println!("Handler {}: {:X}", sig, handler);
if handler == SIG_DFL {
match sig {
SIGCHLD => {
println!("SIGCHLD");
},
SIGCONT => {
println!("Continue");
{
let contexts = contexts();
let (pid, ppid) = {
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
let mut context = context_lock.write();
context.status = Status::Runnable;
(context.id, context.ppid)
};
if let Some(parent_lock) = contexts.get(ppid) {
let waitpid = {
let mut parent = parent_lock.write();
Arc::clone(&parent.waitpid)
};
waitpid.send(pid, 0xFFFF);
} else {
println!("{}: {} not found for continue", pid.into(), ppid.into());
}
}
},
SIGSTOP | SIGTSTP | SIGTTIN | SIGTTOU => {
println!("Stop {}", sig);
{
let contexts = contexts();
let (pid, ppid) = {
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
let mut context = context_lock.write();
context.status = Status::Stopped(sig);
(context.id, context.ppid)
};
if let Some(parent_lock) = contexts.get(ppid) {
let waitpid = {
let mut parent = parent_lock.write();
Arc::clone(&parent.waitpid)
};
waitpid.send(pid, (sig << 8) | 0x7F);
} else {
println!("{}: {} not found for stop", pid.into(), ppid.into());
}
}
},
_ => {
println!("Exit {}", sig);
syscall::exit(sig);
}
}
} else if handler == SIG_IGN {
println!("Ignore");
} else {
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);
}
}
}

View File

@@ -1,13 +1,10 @@
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, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU};
use context::{arch, contexts, Context, Status, CONTEXT_ID};
use context::signal::signal_handler;
use gdt;
use interrupt;
use interrupt::irq::PIT_TICKS;
use syscall;
use time;
/// Switch to the next context
@@ -152,62 +149,3 @@ pub unsafe fn switch() -> bool {
true
}
}
extern "C" fn signal_handler(sig: usize) {
let (action, restorer) = {
let contexts = contexts();
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
let context = context_lock.read();
let actions = context.actions.lock();
actions[sig]
};
let handler = action.sa_handler as usize;
println!("Handler {}: {:X}", sig, handler);
if handler == SIG_DFL {
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();
context.status = Status::Runnable;
}
},
SIGSTOP | SIGTSTP | SIGTTIN | SIGTTOU => {
println!("Stop {}", sig);
{
let contexts = contexts();
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
let mut context = context_lock.write();
context.status = Status::Stopped(sig);
}
},
_ => {
println!("Exit {}", sig);
syscall::exit(sig);
}
}
} else if handler == SIG_IGN {
println!("Ignore");
} else {
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);
}
}
}

View File

@@ -22,7 +22,7 @@ use scheme::FileHandle;
use syscall;
use syscall::data::{SigAction, Stat};
use syscall::error::*;
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, SIG_DFL, SIGTERM, WNOHANG};
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, SIG_DFL, SIGCONT, SIGTERM, WCONTINUED, WNOHANG, WUNTRACED};
use syscall::validate::{validate_slice, validate_slice_mut};
pub fn brk(address: usize) -> Result<usize> {
@@ -974,7 +974,7 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
(context.ruid, context.euid, context.pgid)
};
if sig > 0 && sig <= 0x7F {
if sig > 0 && sig < 0x7F {
let mut found = 0;
let mut sent = 0;
@@ -986,6 +986,12 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
|| euid == context.ruid
|| ruid == context.ruid
{
// Convert stopped processes to blocked if sending SIGCONT
if sig == SIGCONT {
if let context::Status::Stopped(_sig) = context.status {
context.status = context::Status::Blocked;
}
}
context.pending.push_back(sig as u8);
true
} else {
@@ -1158,47 +1164,69 @@ pub fn waitpid(pid: ContextId, status_ptr: usize, flags: usize) -> Result<Contex
&mut tmp
};
if pid.into() == 0 {
if flags & WNOHANG == WNOHANG {
if let Some((w_pid, status)) = waitpid.receive_any_nonblock() {
let mut grim_reaper = |w_pid: ContextId, status: usize| -> Option<Result<ContextId>> {
if status == 0xFFFF {
if flags & WCONTINUED == WCONTINUED {
status_slice[0] = status;
reap(w_pid)
Some(Ok(w_pid))
} else {
Ok(ContextId::from(0))
None
}
} else if status & 0xFF == 0x7F {
if flags & WUNTRACED == WUNTRACED {
status_slice[0] = status;
Some(Ok(w_pid))
} else {
None
}
} else {
let (w_pid, status) = waitpid.receive_any();
status_slice[0] = status;
reap(w_pid)
Some(reap(w_pid))
}
} else {
let status = {
let contexts = context::contexts();
let context_lock = contexts.get(pid).ok_or(Error::new(ECHILD))?;
let mut context = context_lock.write();
if context.ppid != ppid {
println!("Hack for rustc - changing ppid of {} from {} to {}", context.id.into(), context.ppid.into(), ppid.into());
context.ppid = ppid;
//return Err(Error::new(ECHILD));
};
loop {
let res_opt = if pid.into() == 0 {
if flags & WNOHANG == WNOHANG {
if let Some((w_pid, status)) = waitpid.receive_any_nonblock() {
grim_reaper(w_pid, status)
} else {
Some(Ok(ContextId::from(0)))
}
} else {
let (w_pid, status) = waitpid.receive_any();
grim_reaper(w_pid, status)
}
} else {
let status = {
let contexts = context::contexts();
let context_lock = contexts.get(pid).ok_or(Error::new(ECHILD))?;
let mut context = context_lock.write();
if context.ppid != ppid {
println!("Hack for rustc - changing ppid of {} from {} to {}", context.id.into(), context.ppid.into(), ppid.into());
context.ppid = ppid;
//return Err(Error::new(ECHILD));
}
context.status
};
if let context::Status::Exited(status) = status {
let _ = waitpid.receive_nonblock(&pid);
grim_reaper(pid, status)
} else if flags & WNOHANG == WNOHANG {
if let Some(status) = waitpid.receive_nonblock(&pid) {
grim_reaper(pid, status)
} else {
Some(Ok(ContextId::from(0)))
}
} else {
let status = waitpid.receive(&pid);
grim_reaper(pid, status)
}
context.status
};
if let context::Status::Exited(status) = status {
let _ = waitpid.receive_nonblock(&pid);
status_slice[0] = status;
reap(pid)
} else if flags & WNOHANG == WNOHANG {
if let Some(status) = waitpid.receive_nonblock(&pid) {
status_slice[0] = status;
reap(pid)
} else {
Ok(ContextId::from(0))
}
} else {
let status = waitpid.receive(&pid);
status_slice[0] = status;
reap(pid)
if let Some(res) = res_opt {
return res;
}
}
}

Submodule syscall updated: 414b8e0be0...8f01290058