diff --git a/Cargo.lock b/Cargo.lock
index f2933754c0d84a81c5e46a7f730da73387e38792..e2e4c7f559869dc3471d4365fb348e284a224604 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -21,9 +21,9 @@ name = "atty"
 version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -33,9 +33,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -43,8 +43,8 @@ name = "backtrace-sys"
 version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -63,14 +63,14 @@ version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "decimal 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "liner 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cc"
-version = "1.0.3"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -80,7 +80,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "clap"
-version = "2.29.0"
+version = "2.29.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -98,8 +98,8 @@ version = "2.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "ord_subset 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -131,16 +131,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "fuchsia-zircon"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "fuchsia-zircon-sys"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -161,12 +161,12 @@ dependencies = [
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "libloading 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "liner 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "permutate 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallstring 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -202,7 +202,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libc"
-version = "0.2.35"
+version = "0.2.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -230,7 +230,7 @@ name = "memchr"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -250,16 +250,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rand"
-version = "0.3.19"
+version = "0.3.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "redox_syscall"
-version = "0.1.34"
+version = "0.1.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -267,7 +267,7 @@ name = "redox_termios"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "redox_syscall 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -357,8 +357,8 @@ name = "termion"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -407,7 +407,7 @@ name = "users"
 version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -437,11 +437,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "winapi"
-version = "0.3.3"
+version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -451,18 +451,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "winapi-i686-pc-windows-gnu"
-version = "0.3.2"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "winapi-x86_64-pc-windows-gnu"
-version = "0.3.2"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "xdg"
 version = "2.1.0"
-source = "git+https://github.com/whitequark/rust-xdg#a1c9249f78a5395c2ee3dc8688a03c59fe9afe2a"
+source = "git+https://github.com/whitequark/rust-xdg#090afef2509d746e48d6bfa9b2e1ef6dc4564448"
 
 [metadata]
 "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
@@ -474,29 +474,29 @@ source = "git+https://github.com/whitequark/rust-xdg#a1c9249f78a5395c2ee3dc8688a
 "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
 "checksum bytecount 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "4bbeb7c30341fce29f6078b4bdf876ea4779600866e98f5b2d203a534f195050"
 "checksum calculate 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dfe3fe310e5858ba47beb9443acec7fb39b90ea5677d35636306fe7b495a547c"
-"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719"
+"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
-"checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f"
+"checksum clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4151c5790817c7d21bbdc6c3530811f798172915f93258244948b93ba19604a6"
 "checksum decimal 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e6458723bc760383275fbc02f4c769b2e5f3de782abaf5e7e0b9b7f0368a63ed"
 "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
 "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
 "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
-"checksum fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd510087c325af53ba24f3be8f1c081b0982319adcb8b03cad764512923ccc19"
-"checksum fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "08b3a6f13ad6b96572b53ce7af74543132f1a7055ccceb6d073dd36c54481859"
+"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
 "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
-"checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb"
+"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121"
 "checksum libloading 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd38073de8f7965d0c17d30546d4bb6da311ab428d1c7a3fc71dff7f9d4979b9"
 "checksum liner 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e21c5e49e5d73f18124fd3c751a0823f754c5ae7193cb9e8aa467b03b161241c"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
 "checksum ord_subset 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc65e6e24476e1a5baed530f60b918ff7925539aaae1d59ab51113c991321c40"
 "checksum permutate 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53b7d5b19a715ffab38693a9dd44b067fdfa2b18eef65bd93562dfe507022fae"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
-"checksum rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7944d95d25ace8f377da3ac7068ce517e4c646754c43a1b1849177bbf72e59"
-"checksum redox_syscall 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "df1a5c588807af3b0cbbfa2f1358f2d5ec6ad546858c1ccd30dfbb127021706b"
+"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
+"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "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"
@@ -523,8 +523,8 @@ source = "git+https://github.com/whitequark/rust-xdg#a1c9249f78a5395c2ee3dc8688a
 "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-"checksum winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b09fb3b6f248ea4cd42c9a65113a847d612e17505d6ebd1f7357ad68a8bf8693"
+"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
-"checksum winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec6667f60c23eca65c561e63a13d81b44234c2e38a6b6c959025ee907ec614cc"
-"checksum winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98f12c52b2630cd05d2c3ffd8e008f7f48252c042b4871c72aed9dc733b96668"
+"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 "checksum xdg 2.1.0 (git+https://github.com/whitequark/rust-xdg)" = "<none>"
diff --git a/src/lib/lib.rs b/src/lib/lib.rs
index 045da92a627ebc97c1465de637e4336c34df6c1d..733190b7f76b034549071e835ebcd0d38b661636 100644
--- a/src/lib/lib.rs
+++ b/src/lib/lib.rs
@@ -32,7 +32,7 @@ extern crate users as users_unix;
 extern crate xdg;
 
 #[cfg(target_os = "redox")]
-#[path = "sys/redox.rs"]
+#[path = "sys/redox/mod.rs"]
 mod sys;
 
 #[cfg(unix)]
diff --git a/src/lib/sys/redox/job_control.rs b/src/lib/sys/redox/job_control.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3eea413674caee399cb1b9688dd1c54b19885db1
--- /dev/null
+++ b/src/lib/sys/redox/job_control.rs
@@ -0,0 +1,135 @@
+use shell::Shell;
+use shell::foreground::ForegroundSignals;
+use shell::job_control::*;
+use shell::status::{FAILURE, TERMINATED};
+use std::sync::{Arc, Mutex};
+use std::thread::sleep;
+use std::time::Duration;
+use syscall::{
+    kill, waitpid,
+    ECHILD,
+    SIGINT, SIGPIPE,
+    WCONTINUED, WNOHANG, WUNTRACED,
+    wifcontinued, wifexited, wifsignaled, wifstopped,
+    wcoredump, wexitstatus, wstopsig, wtermsig
+};
+
+const OPTS: usize = WUNTRACED | WCONTINUED | WNOHANG;
+
+pub(crate) fn watch_background(
+    fg: Arc<ForegroundSignals>,
+    processes: Arc<Mutex<Vec<BackgroundProcess>>>,
+    pgid: u32,
+    njob: usize,
+) {
+    let mut fg_was_grabbed = false;
+    let mut status;
+    let mut exit_status = 0;
+
+    loop {
+        fg_was_grabbed = !fg_was_grabbed && fg.was_grabbed(pgid);
+
+        unsafe {
+            status = 0;
+            match waitpid(-(pgid as isize) as usize, &mut status, OPTS) {
+                Err(ref err) if err.errno == ECHILD => {
+                    if !fg_was_grabbed {
+                        eprintln!("ion: ([{}] {}) exited with {}", njob, pgid, status);
+                    }
+                    let mut processes = processes.lock().unwrap();
+                    let process = &mut processes.iter_mut().nth(njob).unwrap();
+                    process.state = ProcessState::Empty;
+                    if fg_was_grabbed {
+                        fg.reply_with(exit_status as i8);
+                    }
+                    break;
+                }
+                Err(err) => {
+                    eprintln!("ion: ([{}] {}) errored: {}", njob, pgid, err);
+                    let mut processes = processes.lock().unwrap();
+                    let process = &mut processes.iter_mut().nth(njob).unwrap();
+                    process.state = ProcessState::Empty;
+                    if fg_was_grabbed {
+                        fg.errored();
+                    }
+                    break;
+                }
+                Ok(0) => (),
+                Ok(_pid) if wifexited(status) => exit_status = wexitstatus(status),
+                Ok(_pid) if wifstopped(status) => {
+                    if !fg_was_grabbed {
+                        eprintln!("ion: ([{}] {}) Stopped", njob, pgid);
+                    }
+                    let mut processes = processes.lock().unwrap();
+                    let process = &mut processes.iter_mut().nth(njob).unwrap();
+                    if fg_was_grabbed {
+                        fg.reply_with(TERMINATED as i8);
+                        fg_was_grabbed = false;
+                    }
+                    process.state = ProcessState::Stopped;
+                }
+                Ok(_pid) if wifcontinued(status) => {
+                    if !fg_was_grabbed {
+                        eprintln!("ion: ([{}] {}) Running", njob, pgid);
+                    }
+                    let mut processes = processes.lock().unwrap();
+                    let process = &mut processes.iter_mut().nth(njob).unwrap();
+                    process.state = ProcessState::Running;
+                }
+                _ => (),
+            }
+        }
+        sleep(Duration::from_millis(100));
+    }
+}
+
+pub(crate) fn watch_foreground(shell: &mut Shell, pid: i32, command: &str) -> i32 {
+    let mut signaled = 0;
+    let mut status;
+
+    loop {
+        unsafe {
+            status = 0;
+            match waitpid(pid as usize, &mut status, WUNTRACED) {
+                Err(err) => {
+                    match err.errno {
+                        ECHILD => break signaled,
+                        errno => {
+                            eprintln!("ion: waitpid error: {}", errno);
+                            break FAILURE;
+                        }
+                    }
+                }
+                Ok(0) => (),
+                Ok(_pid) if wifexited(status) => break wexitstatus(status) as i32,
+                Ok(pid) if wifsignaled(status) => {
+                    let signal = wtermsig(status);
+                    if signal == SIGPIPE {
+                        continue
+                    } else if wcoredump(status) {
+                        eprintln!("ion: process ({}) had a core dump", pid);
+                        continue
+                    }
+
+                    eprintln!("ion: process ({}) ended by signal {}", pid, signal);
+                    match signal {
+                        SIGINT => {
+                            let _ = kill(pid, signal as usize);
+                            shell.break_flow = true;
+                        }
+                        _ => {
+                            shell.handle_signal(signal as i32);
+                        }
+                    }
+                    signaled = 128 + signal as i32;
+                }
+                Ok(pid) if wifstopped(status) => {
+                    shell.send_to_background(pid as u32, ProcessState::Stopped, command.into());
+                    shell.break_flow = true;
+                    break 128 + wstopsig(status) as i32;
+                }
+                _ => (),
+            }
+        }
+    }
+}
diff --git a/src/lib/sys/redox.rs b/src/lib/sys/redox/mod.rs
similarity index 73%
rename from src/lib/sys/redox.rs
rename to src/lib/sys/redox/mod.rs
index 62bb6409c72303d2a0d30fad61cabd6a0f7ebe04..49e30169468148d28fbf60b620a6d2018282221e 100644
--- a/src/lib/sys/redox.rs
+++ b/src/lib/sys/redox/mod.rs
@@ -9,6 +9,8 @@ use std::process::{exit, ExitStatus};
 use std::os::unix::process::ExitStatusExt;
 use syscall::{EINTR, WUNTRACED, SigAction, waitpid};
 
+pub mod job_control;
+
 pub(crate) const PATH_SEPARATOR: &str = ";";
 pub(crate) const NULL_PATH: &str = "null:";
 
@@ -253,90 +255,6 @@ pub mod signals {
     pub(crate) fn unblock() {}
 }
 
-pub mod job_control {
-    use shell::job_control::*;
-
-    use shell::Shell;
-    use shell::foreground::ForegroundSignals;
-    use shell::status::FAILURE;
-    use std::os::unix::process::ExitStatusExt;
-    use std::process::ExitStatus;
-    use std::sync::{Arc, Mutex};
-    use syscall::{self, ECHILD, WUNTRACED, waitpid};
-    use super::{SIGINT, SIGPIPE};
-
-    pub(crate) fn watch_background(
-        _fg: Arc<ForegroundSignals>,
-        _processes: Arc<Mutex<Vec<BackgroundProcess>>>,
-        _pid: u32,
-        _njob: usize,
-    ) {
-        // TODO: Implement this using syscall::call::waitpid
-    }
-
-    pub(crate) fn watch_foreground(shell: &mut Shell, pid: i32, command: &str ) -> i32 {
-        let mut signaled = 0;
-        let mut exit_status = 0;
-        let mut status;
-
-        fn get_pid_value(pid: i32) -> usize {
-            if pid < 0 {
-                !(pid.abs() as usize)
-            } else {
-                pid as usize
-            }
-        }
-
-        let pgid = get_pid_value(pid);
-
-        loop {
-            status = 0;
-            let result = waitpid(pgid, &mut status, WUNTRACED);
-            match result {
-                Err(error) => {
-                    match error.errno {
-                        ECHILD if signaled == 0 => break exit_status,
-                        ECHILD => break signaled,
-                        _ => {
-                            eprintln!("ion: waitpid error: {}", error);
-                            break FAILURE;
-                        }
-                    }
-                }
-                Ok(0) => (),
-                Ok(pid) => {
-                    let es = ExitStatus::from_raw(status as i32);
-                    match es.signal() {
-                        Some(SIGPIPE) => continue,
-                        Some(signal) => {
-                            eprintln!("ion: process ended by signal {}", signal);
-                            match signal {
-                                SIGINT => {
-                                    let _ = syscall::kill(pgid, signal as usize);
-                                    shell.break_flow = true;
-                                }
-                                _ => {
-                                    shell.handle_signal(signal);
-                                }
-                            }
-                            signaled = 128 + signal as i32;
-                        }
-                        None => {
-                            exit_status = es.code().unwrap();
-                        }
-                    }
-                }
-                // TODO: Background job control for Redox
-                // _pid if WIFSTOPPED(status) => {
-                //     shell.send_to_background(pid as u32, ProcessState::Stopped, command.into());
-                //     shell.break_flow = true;
-                //     break 128 + signal as i32;
-                // }
-            }
-        }
-    }
-}
-
 pub mod variables {
     pub(crate) fn get_user_home(_username: &str) -> Option<String> {
         // TODO