diff --git a/Cargo.lock b/Cargo.lock
index 92eb0d370480e7d1b90fc4c945be3f2772445039..b81c0586dd2c93cd1fb1d20c6056e14ed39f6c4b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -377,7 +377,7 @@ version = "0.1.0"
 dependencies = [
  "goblin",
  "plain",
- "redox_syscall 0.3.5",
+ "redox_syscall 0.4.1",
 ]
 
 [[package]]
@@ -394,6 +394,15 @@ dependencies = [
  "bitflags",
 ]
 
+[[package]]
+name = "redox_syscall"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
+dependencies = [
+ "bitflags",
+]
+
 [[package]]
 name = "relibc"
 version = "0.2.5"
@@ -413,7 +422,7 @@ dependencies = [
  "ralloc",
  "rand",
  "redox-exec",
- "redox_syscall 0.3.5",
+ "redox_syscall 0.4.1",
  "sc",
  "spin 0.9.8",
  "unicode-width",
diff --git a/Cargo.toml b/Cargo.toml
index 61f84fbbf1347063a47131fa6936bc91ee5f773e..f7ae07026d754bc7456c6d8b220f56681fd28108 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -44,7 +44,7 @@ optional = true
 sc = "0.2.3"
 
 [target.'cfg(target_os = "redox")'.dependencies]
-redox_syscall = "0.3"
+redox_syscall = "0.4"
 spin = "0.9.0"
 redox-exec = { path = "src/platform/redox/redox-exec" }
 
diff --git a/src/platform/redox/libredox.rs b/src/platform/redox/libredox.rs
new file mode 100644
index 0000000000000000000000000000000000000000..07d0fe54466e08e7df1080943639dc04b6b4c842
--- /dev/null
+++ b/src/platform/redox/libredox.rs
@@ -0,0 +1,115 @@
+use core::{slice, str};
+
+use libc::{c_int, mode_t};
+use syscall::{Error, Result, EMFILE, WaitFlags};
+
+use crate::header::signal::sigaction;
+
+pub type RawResult = usize;
+
+pub fn open(path: &str, oflag: c_int, mode: mode_t) -> Result<usize> {
+    let usize_fd = super::path::open(
+        path,
+        ((oflag as usize) & 0xFFFF_0000) | ((mode as usize) & 0xFFFF),
+    )?;
+
+    c_int::try_from(usize_fd).map_err(|_| {
+        let _ = syscall::close(usize_fd);
+        Error::new(EMFILE)
+    }).map(|f| f as usize)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn redox_open_v1(path_base: *const u8, path_len: usize, flags: u32, mode: u16) -> RawResult {
+    Error::mux(open(str::from_utf8_unchecked(slice::from_raw_parts(path_base, path_len)), flags as c_int, mode as mode_t))
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn redox_dup_v1(fd: usize, buf: *const u8, len: usize) -> RawResult {
+    Error::mux(syscall::dup(fd, core::slice::from_raw_parts(buf, len)))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_dup2_v1(old_fd: usize, new_fd: usize, buf: *const u8, len: usize) -> RawResult {
+    Error::mux(syscall::dup2(old_fd, new_fd, core::slice::from_raw_parts(buf, len)))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_read_v1(fd: usize, dst_base: *mut u8, dst_len: usize) -> RawResult {
+    Error::mux(syscall::read(fd, slice::from_raw_parts_mut(dst_base, dst_len)))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_write_v1(fd: usize, src_base: *const u8, src_len: usize) -> RawResult {
+    Error::mux(syscall::write(fd, slice::from_raw_parts(src_base, src_len)))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_fsync_v1(fd: usize) -> RawResult {
+    Error::mux(syscall::fsync(fd))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_fdatasync_v1(fd: usize) -> RawResult {
+    // TODO
+    Error::mux(syscall::fsync(fd))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_fchmod_v1(fd: usize, new_mode: u16) -> RawResult {
+    Error::mux(syscall::fchmod(fd, new_mode))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_fchown_v1(fd: usize, new_uid: u32, new_gid: u32) -> RawResult {
+    Error::mux(syscall::fchown(fd, new_uid, new_gid))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_fpath_v1(fd: usize, dst_base: *mut u8, dst_len: usize) -> RawResult {
+    Error::mux(syscall::fpath(fd, core::slice::from_raw_parts_mut(dst_base, dst_len)))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_close_v1(fd: usize) -> RawResult {
+    Error::mux(syscall::close(fd))
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn redox_get_pid_v1() -> RawResult {
+    Error::mux(syscall::getpid())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn redox_get_euid_v1() -> RawResult {
+    Error::mux(syscall::geteuid())
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_get_ruid_v1() -> RawResult {
+    Error::mux(syscall::getuid())
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_get_egid_v1() -> RawResult {
+    Error::mux(syscall::getegid())
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_get_rgid_v1() -> RawResult {
+    Error::mux(syscall::getgid())
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_setrens_v1(rns: usize, ens: usize) -> RawResult {
+    Error::mux(syscall::setrens(rns, ens))
+}
+#[no_mangle]
+pub unsafe extern "C" fn redox_waitpid_v1(pid: usize, status: *mut i32, options: u32) -> RawResult {
+    let mut sts = 0_usize;
+    let res = Error::mux(syscall::waitpid(pid, &mut sts, WaitFlags::from_bits_truncate(options as usize)));
+    status.write(sts as i32);
+    res
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn redox_kill_v1(pid: usize, signal: u32) -> RawResult {
+    Error::mux(syscall::kill(pid, signal as usize))
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn redox_sigaction_v1(signal: u32, new: *const sigaction, old: *mut sigaction) -> RawResult {
+    Error::mux(super::signal::sigaction_impl(signal as i32, new.as_ref(), old.as_mut()).map(|()| 0))
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn redox_sigprocmask_v1(how: u32, new: *const u64, old: *mut u64) -> RawResult {
+    Error::mux(super::signal::sigprocmask_impl(how as i32, new, old).map(|()| 0))
+}
diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs
index f07b3124dafdc43ee276beb1eeca470ff99a4d0b..c09bb4586b2141118b885fcdd84f51473b5d3ec3 100644
--- a/src/platform/redox/mod.rs
+++ b/src/platform/redox/mod.rs
@@ -43,6 +43,7 @@ mod clone;
 mod epoll;
 mod exec;
 mod extra;
+mod libredox;
 pub(crate) mod path;
 mod ptrace;
 mod signal;
@@ -765,19 +766,7 @@ impl Pal for Sys {
     fn open(path: &CStr, oflag: c_int, mode: mode_t) -> c_int {
         let path = path_from_c_str!(path);
 
-        match path::open(
-            path,
-            ((oflag as usize) & 0xFFFF_0000) | ((mode as usize) & 0xFFFF),
-        ) {
-            Ok(fd) => match c_int::try_from(fd) {
-                Ok(c_fd) => c_fd,
-                Err(_) => {
-                    let _ = syscall::close(fd);
-                    e(Err(Error::new(EMFILE))) as c_int
-                }
-            },
-            Err(error) => e(Err(error)) as c_int,
-        }
+        e(libredox::open(path, oflag, mode)) as c_int
     }
 
     fn pipe2(fds: &mut [c_int], flags: c_int) -> c_int {
diff --git a/src/platform/redox/redox-exec/Cargo.toml b/src/platform/redox/redox-exec/Cargo.toml
index bb1744cab53600494b48aa0a2ffc926bc72ddc75..1a47f79812f1e2925bf8ad5fcacfa34c54a47589 100644
--- a/src/platform/redox/redox-exec/Cargo.toml
+++ b/src/platform/redox/redox-exec/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-redox_syscall = "0.3"
+redox_syscall = "0.4"
 # TODO: Update
 goblin = { version = "0.0.21", default-features = false, features = ["elf32", "elf64", "endian_fd"] }
 plain = "0.2"
diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs
index ef039c6fdbc5a5d58a5dd83508cf39ee708efc36..0b36869b736c4cb3736db68fdc12c8e0ff220aa4 100644
--- a/src/platform/redox/signal.rs
+++ b/src/platform/redox/signal.rs
@@ -1,5 +1,5 @@
 use core::mem;
-use syscall;
+use syscall::{self, Result};
 
 use super::{
     super::{types::*, Pal, PalSignal},
@@ -107,29 +107,7 @@ impl PalSignal for Sys {
     }
 
     fn sigaction(sig: c_int, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> c_int {
-        let new_opt = act.map(|act| {
-            let m = act.sa_mask;
-            let sa_handler = unsafe { mem::transmute(act.sa_handler) };
-            syscall::SigAction {
-                sa_handler,
-                sa_mask: [m as u64, 0],
-                sa_flags: syscall::SigActionFlags::from_bits(act.sa_flags as usize)
-                    .expect("sigaction: invalid bit pattern"),
-            }
-        });
-        let mut old_opt = oact.as_ref().map(|_| syscall::SigAction::default());
-        let ret = e(syscall::sigaction(
-            sig as usize,
-            new_opt.as_ref(),
-            old_opt.as_mut(),
-        )) as c_int;
-        if let (Some(old), Some(oact)) = (old_opt, oact) {
-            oact.sa_handler = unsafe { mem::transmute(old.sa_handler) };
-            let m = old.sa_mask;
-            oact.sa_mask = m[0] as sigset_t;
-            oact.sa_flags = old.sa_flags.bits() as c_ulong;
-        }
-        ret
+        e(sigaction_impl(sig, act, oact).map(|()| 0)) as c_int
     }
 
     fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int {
@@ -144,21 +122,7 @@ impl PalSignal for Sys {
     }
 
     fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
-        let new_opt = if set.is_null() {
-            None
-        } else {
-            Some([unsafe { *set as u64 }, 0])
-        };
-        let mut old_opt = if oset.is_null() { None } else { Some([0, 0]) };
-        let ret = e(syscall::sigprocmask(
-            how as usize,
-            new_opt.as_ref(),
-            old_opt.as_mut(),
-        )) as c_int;
-        if let Some(old) = old_opt {
-            unsafe { *oset = old[0] as sigset_t };
-        }
-        ret
+        e(sigprocmask_impl(how, set, oset).map(|()| 0)) as c_int
     }
 
     fn sigsuspend(set: *const sigset_t) -> c_int {
@@ -175,3 +139,46 @@ impl PalSignal for Sys {
         -1
     }
 }
+
+pub(crate) fn sigaction_impl(sig: i32, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> Result<()> {
+    let new_opt = act.map(|act| {
+        let m = act.sa_mask;
+        let sa_handler = unsafe { mem::transmute(act.sa_handler) };
+        syscall::SigAction {
+            sa_handler,
+            sa_mask: [m as u64, 0],
+            sa_flags: syscall::SigActionFlags::from_bits(act.sa_flags as usize)
+                .expect("sigaction: invalid bit pattern"),
+        }
+    });
+    let mut old_opt = oact.as_ref().map(|_| syscall::SigAction::default());
+    syscall::sigaction(
+        sig as usize,
+        new_opt.as_ref(),
+        old_opt.as_mut(),
+    )?;
+    if let (Some(old), Some(oact)) = (old_opt, oact) {
+        oact.sa_handler = unsafe { mem::transmute(old.sa_handler) };
+        let m = old.sa_mask;
+        oact.sa_mask = m[0] as sigset_t;
+        oact.sa_flags = old.sa_flags.bits() as c_ulong;
+    }
+    Ok(())
+}
+pub(crate) fn sigprocmask_impl(how: i32, set: *const sigset_t, oset: *mut sigset_t) -> Result<()> {
+    let new_opt = if set.is_null() {
+        None
+    } else {
+        Some([unsafe { *set as u64 }, 0])
+    };
+    let mut old_opt = if oset.is_null() { None } else { Some([0, 0]) };
+    syscall::sigprocmask(
+        how as usize,
+        new_opt.as_ref(),
+        old_opt.as_mut(),
+    )?;
+    if let Some(old) = old_opt {
+        unsafe { *oset = old[0] as sigset_t };
+    }
+    Ok(())
+}