diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs
index 276a18bcb8e1bf7212522ee502c6e959a448977d..ccdd0f9b49b3c57479bdb971c3223556751ef5fc 100644
--- a/src/platform/src/linux/mod.rs
+++ b/src/platform/src/linux/mod.rs
@@ -1,9 +1,7 @@
 use core::{mem, ptr};
 use core::fmt::Write;
 
-use FileWriter;
-use Pal;
-use errno;
+use {errno, FileWriter, Pal};
 use types::*;
 
 mod signal;
@@ -81,8 +79,8 @@ impl Pal for Sys {
         e(unsafe { syscall!(DUP3, fildes, fildes2, 0) }) as c_int
     }
 
-    fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
-        e(unsafe { syscall!(EXECVE, path, argv, envp) }) as c_int
+    unsafe fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
+        e(syscall!(EXECVE, path, argv, envp)) as c_int
     }
 
     fn exit(status: c_int) -> ! {
diff --git a/src/platform/src/pal/mod.rs b/src/platform/src/pal/mod.rs
index 752ba7805282dbdb5f33e3d87f3dcb4d30fc1e1d..92410c38828d3414df8361727b1bcde6e6d78fe0 100644
--- a/src/platform/src/pal/mod.rs
+++ b/src/platform/src/pal/mod.rs
@@ -45,7 +45,7 @@ pub trait Pal {
         Self::no_pal("dup2")
     }
 
-    fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
+    unsafe fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
         Self::no_pal("execve")
     }
 
diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs
index 1f4b996ace2e0493ae35bb703a5eb108b737c8c3..41750b789352790a45961280aab8527e03e22dc4 100644
--- a/src/platform/src/redox/mod.rs
+++ b/src/platform/src/redox/mod.rs
@@ -1,18 +1,19 @@
 //! sys/socket implementation, following http://pubs.opengroup.org/onlinepubs/009696699/basedefs/sys/socket.h.html
 
 use alloc::btree_map::BTreeMap;
-use core::fmt::Write;
 use core::{mem, ptr, slice};
+use core::fmt::Write;
 use spin::{Once, Mutex, MutexGuard};
 use syscall::data::Stat as redox_stat;
 use syscall::data::TimeSpec as redox_timespec;
 use syscall::flag::*;
 use syscall::{self, Result};
 
+use {c_str, errno, FileReader, FileWriter, Pal, RawFile, Read};
 use types::*;
-use *;
 
 const EINVAL: c_int = 22;
+const ENOSYS: c_int = 38;
 const MAP_ANON: c_int = 1;
 
 #[thread_local]
@@ -42,1073 +43,737 @@ fn e(sys: Result<usize>) -> usize {
     }
 }
 
-macro_rules! bind_or_connect {
-    (bind $path:expr) => {
-        concat!("/", $path)
-    };
-    (connect $path:expr) => {
-        $path
-    };
-    ($mode:ident $socket:expr, $address:expr, $address_len:expr) => {{
-        if (*$address).sa_family as c_int != AF_INET {
-            errno = syscall::EAFNOSUPPORT;
-            return -1;
+pub struct Sys;
+
+impl Pal for Sys {
+    fn no_pal(name: &str) -> c_int {
+        let _ = writeln!(FileWriter(2), "relibc: no_pal: {}", name);
+        unsafe {
+            errno = ENOSYS;
         }
-        if ($address_len as usize) < mem::size_of::<sockaddr>() {
-            errno = syscall::EINVAL;
+        -1
+    }
+
+    fn access(path: *const c_char, mode: c_int) -> c_int {
+        let fd = match RawFile::open(path, 0, 0) {
+            Ok(fd) => fd,
+            Err(_) => return -1
+        };
+        if mode == F_OK {
+            return 0;
+        }
+
+        let mut stat = syscall::Stat::default();
+
+        if e(syscall::fstat(*fd as usize, &mut stat)) == !0 {
             return -1;
         }
-        let data = &*($address as *const sockaddr_in);
-        let addr = &data.sin_addr.s_addr;
-        let port = in_port_t::from_be(data.sin_port); // This is transmuted from bytes in BigEndian order
-        let path = format!(bind_or_connect!($mode "{}.{}.{}.{}:{}"), addr[0], addr[1], addr[2], addr[3], port);
-
-        // Duplicate the socket, and then duplicate the copy back to the original fd
-        let fd = e(syscall::dup($socket as usize, path.as_bytes()));
-        if (fd as c_int) < 0 {
+
+        let uid = e(syscall::getuid());
+        if uid == !0 {
             return -1;
         }
-        let result = syscall::dup2(fd, $socket as usize, &[]);
-        let _ = syscall::close(fd);
-        if (e(result) as c_int) < 0 {
+        let gid = e(syscall::getgid());
+        if gid == !0 {
             return -1;
         }
-        0
-    }}
-}
 
-pub unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
-    let stream = e(syscall::dup(socket as usize, b"listen")) as c_int;
-    if stream < 0 {
-        return -1;
-    }
-    if address != ptr::null_mut()
-        && address_len != ptr::null_mut()
-        && getpeername(stream, address, address_len) < 0
-    {
-        return -1;
-    }
-    stream
-}
+        let perms = if stat.st_uid as usize == uid {
+            // octal has max 7 characters, binary has max two. And we're interested
+            // in the 3rd digit
+            stat.st_mode >> ((7 / 2) * 2 & 0o7)
+        } else if stat.st_gid as usize == gid {
+            stat.st_mode >> ((7 / 2) & 0o7)
+        } else {
+            stat.st_mode & 0o7
+        };
+        if (mode & R_OK == R_OK && perms & 0o4 != 0o4)
+                || (mode & W_OK == W_OK && perms & 0o2 != 0o2)
+                || (mode & X_OK == X_OK && perms & 0o1 != 0o1) {
+            unsafe {
+                errno = EINVAL;
+            }
+            return -1;
+        }
 
-pub fn access(path: *const c_char, mode: c_int) -> c_int {
-    let fd = match RawFile::open(path, 0, 0) {
-        Ok(fd) => fd,
-        Err(_) => return -1
-    };
-    if mode == F_OK {
-        return 0;
+        0
     }
 
-    let mut stat = syscall::Stat::default();
-
-    if e(syscall::fstat(*fd as usize, &mut stat)) == !0 {
-        return -1;
+    fn brk(addr: *mut c_void) -> *mut c_void {
+        unsafe { syscall::brk(addr as usize).unwrap_or(0) as *mut c_void }
     }
 
-    let uid = e(syscall::getuid());
-    if uid == !0 {
-        return -1;
-    }
-    let gid = e(syscall::getgid());
-    if gid == !0 {
-        return -1;
+    fn chdir(path: *const c_char) -> c_int {
+        let path = unsafe { c_str(path) };
+        e(syscall::chdir(path)) as c_int
     }
 
-    let perms = if stat.st_uid as usize == uid {
-        // octal has max 7 characters, binary has max two. And we're interested
-        // in the 3rd digit
-        stat.st_mode >> ((7 / 2) * 2 & 0o7)
-    } else if stat.st_gid as usize == gid {
-        stat.st_mode >> ((7 / 2) & 0o7)
-    } else {
-        stat.st_mode & 0o7
-    };
-    if (mode & R_OK == R_OK && perms & 0o4 != 0o4)
-            || (mode & W_OK == W_OK && perms & 0o2 != 0o2)
-            || (mode & X_OK == X_OK && perms & 0o1 != 0o1) {
-        unsafe {
-            errno = EINVAL;
+    fn chmod(path: *const c_char, mode: mode_t) -> c_int {
+        let path = unsafe { c_str(path) };
+        match syscall::open(path, O_WRONLY) {
+            Err(err) => e(Err(err)) as c_int,
+            Ok(fd) => {
+                let res = syscall::fchmod(fd as usize, mode as u16);
+                let _ = syscall::close(fd);
+                e(res) as c_int
+            }
         }
-        return -1;
     }
 
-    0
-}
-
-pub unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
-    bind_or_connect!(bind socket, address, address_len)
-}
-
-pub fn brk(addr: *mut c_void) -> *mut c_void {
-    unsafe { syscall::brk(addr as usize).unwrap_or(0) as *mut c_void }
-}
-
-pub fn chdir(path: *const c_char) -> c_int {
-    let path = unsafe { c_str(path) };
-    e(syscall::chdir(path)) as c_int
-}
-
-pub fn chmod(path: *const c_char, mode: mode_t) -> c_int {
-    let path = unsafe { c_str(path) };
-    match syscall::open(path, O_WRONLY) {
-        Err(err) => e(Err(err)) as c_int,
-        Ok(fd) => {
-            let res = syscall::fchmod(fd as usize, mode as u16);
-            let _ = syscall::close(fd);
-            e(res) as c_int
+    fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
+        let path = unsafe { c_str(path) };
+        match syscall::open(path, O_WRONLY) {
+            Err(err) => e(Err(err)) as c_int,
+            Ok(fd) => {
+                let res = syscall::fchown(fd as usize, owner as u32, group as u32);
+                let _ = syscall::close(fd);
+                e(res) as c_int
+            }
         }
     }
-}
 
-pub fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
-    let path = unsafe { c_str(path) };
-    match syscall::open(path, O_WRONLY) {
-        Err(err) => e(Err(err)) as c_int,
-        Ok(fd) => {
-            let res = syscall::fchown(fd as usize, owner as u32, group as u32);
-            let _ = syscall::close(fd);
-            e(res) as c_int
+    fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int {
+        let mut redox_tp = unsafe { redox_timespec::from(&*tp) };
+        match e(syscall::clock_gettime(clk_id as usize, &mut redox_tp)) as c_int {
+            -1 => -1,
+            _ => {
+                unsafe {
+                    (*tp).tv_sec = redox_tp.tv_sec;
+                    (*tp).tv_nsec = redox_tp.tv_nsec as i64;
+                };
+                0
+            }
         }
     }
-}
-
-pub fn close(fd: c_int) -> c_int {
-    e(syscall::close(fd as usize)) as c_int
-}
 
-pub unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
-    bind_or_connect!(connect socket, address, address_len)
-}
-
-pub fn dup(fd: c_int) -> c_int {
-    e(syscall::dup(fd as usize, &[])) as c_int
-}
+    fn close(fd: c_int) -> c_int {
+        e(syscall::close(fd as usize)) as c_int
+    }
 
-pub fn dup2(fd1: c_int, fd2: c_int) -> c_int {
-    e(syscall::dup2(fd1 as usize, fd2 as usize, &[])) as c_int
-}
+    fn dup(fd: c_int) -> c_int {
+        e(syscall::dup(fd as usize, &[])) as c_int
+    }
 
-pub fn exit(status: c_int) -> ! {
-    let _ = syscall::exit(status as usize);
-    loop {}
-}
+    fn dup2(fd1: c_int, fd2: c_int) -> c_int {
+        e(syscall::dup2(fd1 as usize, fd2 as usize, &[])) as c_int
+    }
 
-pub unsafe extern "C" fn execve(
-    path: *const c_char,
-    mut argv: *const *mut c_char,
-    mut envp: *const *mut c_char,
-) -> c_int {
-    use alloc::Vec;
-
-    let fd = match RawFile::open(path, O_RDONLY as c_int, 0) {
-        Ok(fd) => fd,
-        Err(_) => return -1
-    };
-
-    let mut len = 0;
-    while !(*argv.offset(len)).is_null() {
-        len += 1;
+    fn exit(status: c_int) -> ! {
+        let _ = syscall::exit(status as usize);
+        loop {}
     }
 
-    let mut args: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
-    while !(*argv).is_null() {
-        let arg = *argv;
+    unsafe fn execve(
+        path: *const c_char,
+        mut argv: *const *mut c_char,
+        mut envp: *const *mut c_char,
+    ) -> c_int {
+        use alloc::Vec;
+
+        let fd = match RawFile::open(path, O_RDONLY as c_int, 0) {
+            Ok(fd) => fd,
+            Err(_) => return -1
+        };
 
         let mut len = 0;
-        while *arg.offset(len) != 0 {
+        while !(*argv.offset(len)).is_null() {
             len += 1;
         }
-        args.push([arg as usize, len as usize]);
-        argv = argv.offset(1);
-    }
 
-    let mut len = 0;
-    while !(*envp.offset(len)).is_null() {
-        len += 1;
-    }
+        let mut args: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
+        while !(*argv).is_null() {
+            let arg = *argv;
 
-    let mut envs: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
-    while !(*envp).is_null() {
-        let env = *envp;
+            let mut len = 0;
+            while *arg.offset(len) != 0 {
+                len += 1;
+            }
+            args.push([arg as usize, len as usize]);
+            argv = argv.offset(1);
+        }
 
         let mut len = 0;
-        while *env.offset(len) != 0 {
+        while !(*envp.offset(len)).is_null() {
             len += 1;
         }
-        envs.push([env as usize, len as usize]);
-        envp = envp.offset(1);
-    }
 
-    e(syscall::fexec(*fd as usize, &args, &envs)) as c_int
-}
+        let mut envs: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
+        while !(*envp).is_null() {
+            let env = *envp;
 
-pub fn fchdir(fd: c_int) -> c_int {
-    let path: &mut [u8] = &mut [0; 4096];
-    if e(syscall::fpath(fd as usize, path)) == !0 {
-        !0
-    } else {
-        e(syscall::chdir(path)) as c_int
+            let mut len = 0;
+            while *env.offset(len) != 0 {
+                len += 1;
+            }
+            envs.push([env as usize, len as usize]);
+            envp = envp.offset(1);
+        }
+
+        e(syscall::fexec(*fd as usize, &args, &envs)) as c_int
     }
-}
 
-pub fn fchmod(fd: c_int, mode: mode_t) -> c_int {
-    e(syscall::fchmod(fd as usize, mode as u16)) as c_int
-}
+    fn fchdir(fd: c_int) -> c_int {
+        let path: &mut [u8] = &mut [0; 4096];
+        if e(syscall::fpath(fd as usize, path)) == !0 {
+            !0
+        } else {
+            e(syscall::chdir(path)) as c_int
+        }
+    }
 
-pub fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> c_int {
-    e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int
-}
+    fn fchmod(fd: c_int, mode: mode_t) -> c_int {
+        e(syscall::fchmod(fd as usize, mode as u16)) as c_int
+    }
 
-pub fn fcntl(fd: c_int, cmd: c_int, args: c_int) -> c_int {
-    e(syscall::fcntl(fd as usize, cmd as usize, args as usize)) as c_int
-}
+    fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> c_int {
+        e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int
+    }
 
-pub fn flock(_fd: c_int, _operation: c_int) -> c_int {
-    // TODO: Redox does not have file locking yet
-    0
-}
+    fn fcntl(fd: c_int, cmd: c_int, args: c_int) -> c_int {
+        e(syscall::fcntl(fd as usize, cmd as usize, args as usize)) as c_int
+    }
 
-pub fn fork() -> pid_t {
-    e(unsafe { syscall::clone(0) }) as pid_t
-}
+    fn flock(_fd: c_int, _operation: c_int) -> c_int {
+        // TODO: Redox does not have file locking yet
+        0
+    }
 
-pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
-    let mut redox_buf: redox_stat = redox_stat::default();
-    match e(syscall::fstat(fildes as usize, &mut redox_buf)) {
-        0 => {
-            unsafe {
-                if !buf.is_null() {
-                    (*buf).st_dev = redox_buf.st_dev as dev_t;
-                    (*buf).st_ino = redox_buf.st_ino as ino_t;
-                    (*buf).st_nlink = redox_buf.st_nlink as nlink_t;
-                    (*buf).st_mode = redox_buf.st_mode as mode_t;
-                    (*buf).st_uid = redox_buf.st_uid as uid_t;
-                    (*buf).st_gid = redox_buf.st_gid as gid_t;
-                    // TODO st_rdev
-                    (*buf).st_rdev = 0;
-                    (*buf).st_size = redox_buf.st_size as off_t;
-                    (*buf).st_blksize = redox_buf.st_blksize as blksize_t;
-                    (*buf).st_atim = timespec {
-                        tv_sec: redox_buf.st_atime as time_t,
-                        tv_nsec: redox_buf.st_atime_nsec as c_long,
-                    };
-                    (*buf).st_mtim = timespec {
-                        tv_sec: redox_buf.st_mtime as time_t,
-                        tv_nsec: redox_buf.st_mtime_nsec as c_long,
-                    };
-                    (*buf).st_ctim = timespec {
-                        tv_sec: redox_buf.st_ctime as time_t,
-                        tv_nsec: redox_buf.st_ctime_nsec as c_long,
-                    };
+    fn fork() -> pid_t {
+        e(unsafe { syscall::clone(0) }) as pid_t
+    }
+
+    fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
+        let mut redox_buf: redox_stat = redox_stat::default();
+        match e(syscall::fstat(fildes as usize, &mut redox_buf)) {
+            0 => {
+                unsafe {
+                    if !buf.is_null() {
+                        (*buf).st_dev = redox_buf.st_dev as dev_t;
+                        (*buf).st_ino = redox_buf.st_ino as ino_t;
+                        (*buf).st_nlink = redox_buf.st_nlink as nlink_t;
+                        (*buf).st_mode = redox_buf.st_mode as mode_t;
+                        (*buf).st_uid = redox_buf.st_uid as uid_t;
+                        (*buf).st_gid = redox_buf.st_gid as gid_t;
+                        // TODO st_rdev
+                        (*buf).st_rdev = 0;
+                        (*buf).st_size = redox_buf.st_size as off_t;
+                        (*buf).st_blksize = redox_buf.st_blksize as blksize_t;
+                        (*buf).st_atim = timespec {
+                            tv_sec: redox_buf.st_atime as time_t,
+                            tv_nsec: redox_buf.st_atime_nsec as c_long,
+                        };
+                        (*buf).st_mtim = timespec {
+                            tv_sec: redox_buf.st_mtime as time_t,
+                            tv_nsec: redox_buf.st_mtime_nsec as c_long,
+                        };
+                        (*buf).st_ctim = timespec {
+                            tv_sec: redox_buf.st_ctime as time_t,
+                            tv_nsec: redox_buf.st_ctime_nsec as c_long,
+                        };
+                    }
                 }
+                0
             }
-            0
+            _ => -1,
         }
-        _ => -1,
     }
-}
 
-pub fn fsync(fd: c_int) -> c_int {
-    e(syscall::fsync(fd as usize)) as c_int
-}
+    fn fsync(fd: c_int) -> c_int {
+        e(syscall::fsync(fd as usize)) as c_int
+    }
 
-pub fn ftruncate(fd: c_int, len: off_t) -> c_int {
-    e(syscall::ftruncate(fd as usize, len as usize)) as c_int
-}
+    fn ftruncate(fd: c_int, len: off_t) -> c_int {
+        e(syscall::ftruncate(fd as usize, len as usize)) as c_int
+    }
 
-pub fn futimens(fd: c_int, times: *const timespec) -> c_int {
-    let times = [unsafe { redox_timespec::from(&*times) }, unsafe {
-        redox_timespec::from(&*times.offset(1))
-    }];
-    e(syscall::futimens(fd as usize, &times)) as c_int
-}
+    fn futimens(fd: c_int, times: *const timespec) -> c_int {
+        let times = [unsafe { redox_timespec::from(&*times) }, unsafe {
+            redox_timespec::from(&*times.offset(1))
+        }];
+        e(syscall::futimens(fd as usize, &times)) as c_int
+    }
 
-pub fn utimens(path: *const c_char, times: *const timespec) -> c_int {
-    let path = unsafe { c_str(path) };
-    match syscall::open(path, O_STAT) {
-        Err(err) => e(Err(err)) as c_int,
-        Ok(fd) => {
-            let res = futimens(fd as c_int, times);
-            let _ = syscall::close(fd);
-            res
+    fn utimens(path: *const c_char, times: *const timespec) -> c_int {
+        let path = unsafe { c_str(path) };
+        match syscall::open(path, O_STAT) {
+            Err(err) => e(Err(err)) as c_int,
+            Ok(fd) => {
+                let res = Self::futimens(fd as c_int, times);
+                let _ = syscall::close(fd);
+                res
+            }
         }
     }
-}
 
-pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
-    let buf_slice = unsafe { slice::from_raw_parts_mut(buf as *mut u8, size as usize - 1) };
-    let read = e(syscall::getcwd(buf_slice));
-    if read == !0 {
-        ptr::null_mut()
-    } else {
-        unsafe {
-            *buf.offset(read as isize + 1) = 0;
+    fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
+        let buf_slice = unsafe { slice::from_raw_parts_mut(buf as *mut u8, size as usize - 1) };
+        let read = e(syscall::getcwd(buf_slice));
+        if read == !0 {
+            ptr::null_mut()
+        } else {
+            unsafe {
+                *buf.offset(read as isize + 1) = 0;
+            }
+            buf
         }
-        buf
     }
-}
-
-pub fn getdents(fd: c_int, mut dirents: *mut dirent, mut bytes: usize) -> c_int {
-    let mut amount = 0;
 
-    let mut buf = [0; 1024];
-    let mut bindex = 0;
-    let mut blen = 0;
+    fn getdents(fd: c_int, mut dirents: *mut dirent, mut bytes: usize) -> c_int {
+        let mut amount = 0;
 
-    let mut name = [0; 256];
-    let mut nindex = 0;
+        let mut buf = [0; 1024];
+        let mut bindex = 0;
+        let mut blen = 0;
 
-    loop {
-        if bindex >= blen {
-            bindex = 0;
-            blen = match syscall::read(fd as usize, &mut buf) {
-                Ok(0) => return amount,
-                Ok(n) => n,
-                Err(err) => return -err.errno,
-            };
-        }
+        let mut name = [0; 256];
+        let mut nindex = 0;
 
-        if buf[bindex] == b'\n' {
-            // Put a NUL byte either at the end, or if it's too big, at where it's truncated.
-            name[nindex.min(name.len() - 1)] = 0;
-            unsafe {
-                *dirents = dirent {
-                    d_ino: 0,
-                    d_off: 0,
-                    d_reclen: mem::size_of::<dirent>() as c_ushort,
-                    d_type: 0,
-                    d_name: name,
+        loop {
+            if bindex >= blen {
+                bindex = 0;
+                blen = match syscall::read(fd as usize, &mut buf) {
+                    Ok(0) => return amount,
+                    Ok(n) => n,
+                    Err(err) => return -err.errno,
                 };
-                dirents = dirents.offset(1);
             }
-            amount += 1;
-            if bytes <= mem::size_of::<dirent>() {
-                return amount;
-            }
-            bytes -= mem::size_of::<dirent>();
-        } else {
-            if nindex < name.len() {
-                name[nindex] = buf[bindex] as c_char;
+
+            if buf[bindex] == b'\n' {
+                // Put a NUL byte either at the end, or if it's too big, at where it's truncated.
+                name[nindex.min(name.len() - 1)] = 0;
+                unsafe {
+                    *dirents = dirent {
+                        d_ino: 0,
+                        d_off: 0,
+                        d_reclen: mem::size_of::<dirent>() as c_ushort,
+                        d_type: 0,
+                        d_name: name,
+                    };
+                    dirents = dirents.offset(1);
+                }
+                amount += 1;
+                if bytes <= mem::size_of::<dirent>() {
+                    return amount;
+                }
+                bytes -= mem::size_of::<dirent>();
+            } else {
+                if nindex < name.len() {
+                    name[nindex] = buf[bindex] as c_char;
+                }
+                nindex += 1;
+                bindex += 1;
             }
-            nindex += 1;
-            bindex += 1;
         }
     }
-}
 
-pub fn getegid() -> gid_t {
-    e(syscall::getegid()) as gid_t
-}
-
-pub fn geteuid() -> uid_t {
-    e(syscall::geteuid()) as uid_t
-}
-
-pub fn getgid() -> gid_t {
-    e(syscall::getgid()) as gid_t
-}
+    fn getegid() -> gid_t {
+        e(syscall::getegid()) as gid_t
+    }
 
-pub fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int {
-    let _ = writeln!(
-        FileWriter(2),
-        "unimplemented: getrusage({}, {:p})",
-        who,
-        r_usage
-    );
-    -1
-}
+    fn geteuid() -> uid_t {
+        e(syscall::geteuid()) as uid_t
+    }
 
-pub unsafe fn gethostname(mut name: *mut c_char, len: size_t) -> c_int {
-    let fd = e(syscall::open("/etc/hostname", O_RDONLY)) as i32;
-    if fd < 0 {
-        return fd;
+    fn getgid() -> gid_t {
+        e(syscall::getgid()) as gid_t
     }
-    let mut reader = FileReader(fd);
-    for _ in 0..len {
-        match reader.read_u8() {
-            Ok(Some(b)) => {
-                *name = b as c_char;
-                name = name.offset(1);
-            },
-            Ok(None) => {
-                *name = 0;
-                break;
-            },
-            Err(()) => return -1
+
+    unsafe fn gethostname(mut name: *mut c_char, len: size_t) -> c_int {
+        let fd = e(syscall::open("/etc/hostname", O_RDONLY)) as i32;
+        if fd < 0 {
+            return fd;
         }
+        let mut reader = FileReader(fd);
+        for _ in 0..len {
+            match reader.read_u8() {
+                Ok(Some(b)) => {
+                    *name = b as c_char;
+                    name = name.offset(1);
+                },
+                Ok(None) => {
+                    *name = 0;
+                    break;
+                },
+                Err(()) => return -1
+            }
+        }
+        0
     }
-    0
-}
 
-unsafe fn inner_get_name(
-    local: bool,
-    socket: c_int,
-    address: *mut sockaddr,
-    address_len: *mut socklen_t,
-) -> Result<usize> {
-    // 32 should probably be large enough.
-    // Format: tcp:remote/local
-    // and since we only yet support IPv4 (I think)...
-    let mut buf = [0; 32];
-    let len = syscall::fpath(socket as usize, &mut buf)?;
-    let buf = &buf[..len];
-    assert!(&buf[..4] == b"tcp:" || &buf[..4] == b"udp:");
-    let buf = &buf[4..];
-
-    let mut parts = buf.split(|c| *c == b'/');
-    if local {
-        // Skip the remote part
-        parts.next();
+    fn getpgid(pid: pid_t) -> pid_t {
+        e(syscall::getpgid(pid as usize)) as pid_t
     }
-    let part = parts.next().expect("Invalid reply from netstack");
-
-    let data = slice::from_raw_parts_mut(
-        &mut (*address).data as *mut _ as *mut u8,
-        (*address).data.len(),
-    );
-
-    let len = data.len().min(part.len());
-    data[..len].copy_from_slice(&part[..len]);
-
-    *address_len = len as socklen_t;
-    Ok(0)
-}
-
-pub fn getitimer(which: c_int, out: *mut itimerval) -> c_int {
-    let _ = writeln!(
-        FileWriter(2),
-        "unimplemented: getitimer({}, {:p})",
-        which,
-        out
-    );
 
-    unsafe {
-        *out = itimerval::default();
+    fn getpid() -> pid_t {
+        e(syscall::getpid()) as pid_t
     }
-    0
-}
 
-pub unsafe fn getpeername(
-    socket: c_int,
-    address: *mut sockaddr,
-    address_len: *mut socklen_t,
-) -> c_int {
-    e(inner_get_name(false, socket, address, address_len)) as c_int
-}
+    fn getppid() -> pid_t {
+        e(syscall::getppid()) as pid_t
+    }
 
-pub fn getpgid(pid: pid_t) -> pid_t {
-    e(syscall::getpgid(pid as usize)) as pid_t
-}
+    fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
+        let mut redox_tp = redox_timespec::default();
+        let err = e(syscall::clock_gettime(
+            syscall::CLOCK_REALTIME,
+            &mut redox_tp,
+        )) as c_int;
+        if err < 0 {
+            return err;
+        }
+        unsafe {
+            (*tp).tv_sec = redox_tp.tv_sec as time_t;
+            (*tp).tv_usec = (redox_tp.tv_nsec / 1000) as suseconds_t;
 
-pub fn getpid() -> pid_t {
-    e(syscall::getpid()) as pid_t
-}
+            if !tzp.is_null() {
+                (*tzp).tz_minuteswest = 0;
+                (*tzp).tz_dsttime = 0;
+            }
+        }
+        0
+    }
 
-pub fn getppid() -> pid_t {
-    e(syscall::getppid()) as pid_t
-}
+    fn getuid() -> uid_t {
+        e(syscall::getuid()) as pid_t
+    }
 
-pub unsafe fn getsockname(
-    socket: c_int,
-    address: *mut sockaddr,
-    address_len: *mut socklen_t,
-) -> c_int {
-    e(inner_get_name(true, socket, address, address_len)) as c_int
-}
+    fn isatty(fd: c_int) -> c_int {
+        syscall::dup(fd as usize, b"termios")
+            .map(|fd| {
+                let _ = syscall::close(fd);
+                1
+            })
+            .unwrap_or(0)
+    }
 
-pub fn getsockopt(
-    socket: c_int,
-    level: c_int,
-    option_name: c_int,
-    option_value: *mut c_void,
-    option_len: *mut socklen_t,
-) -> c_int {
-    let _ = writeln!(
-        FileWriter(2),
-        "unimplemented: getsockopt({}, {}, {}, {:p}, {:p})",
-        socket,
-        level,
-        option_name,
-        option_value,
-        option_len
-    );
-    -1
-}
+    fn link(path1: *const c_char, path2: *const c_char) -> c_int {
+        let path1 = unsafe { c_str(path1) };
+        let path2 = unsafe { c_str(path2) };
+        e(unsafe { syscall::link(path1.as_ptr(), path2.as_ptr()) }) as c_int
+    }
 
-pub fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
-    let mut redox_tp = redox_timespec::default();
-    let err = e(syscall::clock_gettime(
-        syscall::CLOCK_REALTIME,
-        &mut redox_tp,
-    )) as c_int;
-    if err < 0 {
-        return err;
+    fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t {
+        e(syscall::lseek(
+            fd as usize,
+            offset as isize,
+            whence as usize,
+        )) as off_t
     }
-    unsafe {
-        (*tp).tv_sec = redox_tp.tv_sec as time_t;
-        (*tp).tv_usec = (redox_tp.tv_nsec / 1000) as suseconds_t;
 
-        if !tzp.is_null() {
-            (*tzp).tz_minuteswest = 0;
-            (*tzp).tz_dsttime = 0;
+    fn lstat(path: *const c_char, buf: *mut stat) -> c_int {
+        let path = unsafe { c_str(path) };
+        match syscall::open(path, O_STAT | O_NOFOLLOW) {
+            Err(err) => e(Err(err)) as c_int,
+            Ok(fd) => {
+                let res = Self::fstat(fd as i32, buf);
+                let _ = syscall::close(fd);
+                res
+            }
         }
     }
-    0
-}
-
-pub fn getuid() -> uid_t {
-    e(syscall::getuid()) as pid_t
-}
-
-pub fn isatty(fd: c_int) -> c_int {
-    syscall::dup(fd as usize, b"termios")
-        .map(|fd| {
-            let _ = syscall::close(fd);
-            1
-        })
-        .unwrap_or(0)
-}
-
-pub fn kill(pid: pid_t, sig: c_int) -> c_int {
-    e(syscall::kill(pid as usize, sig as usize)) as c_int
-}
 
-pub fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
-    e(syscall::kill(-(pgrp as isize) as usize, sig as usize)) as c_int
-}
-
-pub fn link(path1: *const c_char, path2: *const c_char) -> c_int {
-    let path1 = unsafe { c_str(path1) };
-    let path2 = unsafe { c_str(path2) };
-    e(unsafe { syscall::link(path1.as_ptr(), path2.as_ptr()) }) as c_int
-}
+    fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
+        let flags = O_CREAT | O_EXCL | O_CLOEXEC | O_DIRECTORY | mode as usize & 0o777;
+        let path = unsafe { c_str(path) };
+        match syscall::open(path, flags) {
+            Ok(fd) => {
+                let _ = syscall::close(fd);
+                0
+            }
+            Err(err) => e(Err(err)) as c_int,
+        }
+    }
 
-pub fn listen(_socket: c_int, _backlog: c_int) -> c_int {
-    // TODO
-    0
-}
+    fn mkfifo(path: *const c_char, mode: mode_t) -> c_int {
+        let flags = O_CREAT | MODE_FIFO as usize | mode as usize & 0o777;
+        let path = unsafe { c_str(path) };
+        match syscall::open(path, flags) {
+            Ok(fd) => {
+                let _ = syscall::close(fd);
+                0
+            }
+            Err(err) => e(Err(err)) as c_int,
+        }
+    }
+
+    unsafe fn mmap(
+        _addr: *mut c_void,
+        len: usize,
+        _prot: c_int,
+        flags: c_int,
+        fildes: c_int,
+        off: off_t,
+    ) -> *mut c_void {
+        if flags & MAP_ANON == MAP_ANON {
+            let fd = e(syscall::open("memory:", 0)); // flags don't matter currently
+            if fd == !0 {
+                return !0 as *mut c_void;
+            }
 
-pub fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t {
-    e(syscall::lseek(
-        fd as usize,
-        offset as isize,
-        whence as usize,
-    )) as off_t
-}
+            let addr = e(syscall::fmap(fd, off as usize, len as usize));
+            if addr == !0 {
+                let _ = syscall::close(fd);
+                return !0 as *mut c_void;
+            }
 
-pub fn lstat(path: *const c_char, buf: *mut stat) -> c_int {
-    let path = unsafe { c_str(path) };
-    match syscall::open(path, O_STAT | O_NOFOLLOW) {
-        Err(err) => e(Err(err)) as c_int,
-        Ok(fd) => {
-            let res = fstat(fd as i32, buf);
-            let _ = syscall::close(fd);
-            res
+            anonymous_maps().insert(addr as usize, fd);
+            addr as *mut c_void
+        } else {
+            e(syscall::fmap(fildes as usize, off as usize, len as usize)) as *mut c_void
         }
     }
-}
 
-pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
-    let flags = O_CREAT | O_EXCL | O_CLOEXEC | O_DIRECTORY | mode as usize & 0o777;
-    let path = unsafe { c_str(path) };
-    match syscall::open(path, flags) {
-        Ok(fd) => {
-            let _ = syscall::close(fd);
-            0
+    unsafe fn munmap(addr: *mut c_void, _len: usize) -> c_int {
+        if e(syscall::funmap(addr as usize)) == !0 {
+            return !0;
         }
-        Err(err) => e(Err(err)) as c_int,
-    }
-}
-
-pub fn mkfifo(path: *const c_char, mode: mode_t) -> c_int {
-    let flags = O_CREAT | MODE_FIFO as usize | mode as usize & 0o777;
-    let path = unsafe { c_str(path) };
-    match syscall::open(path, flags) {
-        Ok(fd) => {
+        if let Some(fd) = anonymous_maps().remove(&(addr as usize)) {
             let _ = syscall::close(fd);
-            0
         }
-        Err(err) => e(Err(err)) as c_int,
+        0
     }
-}
 
-pub unsafe fn mmap(
-    _addr: *mut c_void,
-    len: usize,
-    _prot: c_int,
-    flags: c_int,
-    fildes: c_int,
-    off: off_t,
-) -> *mut c_void {
-    if flags & MAP_ANON == MAP_ANON {
-        let fd = e(syscall::open("memory:", 0)); // flags don't matter currently
-        if fd == !0 {
-            return !0 as *mut c_void;
-        }
-
-        let addr = e(syscall::fmap(fd, off as usize, len as usize));
-        if addr == !0 {
-            let _ = syscall::close(fd);
-            return !0 as *mut c_void;
+    fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
+        let redox_rqtp = unsafe { redox_timespec::from(&*rqtp) };
+        let mut redox_rmtp: redox_timespec;
+        if rmtp.is_null() {
+            redox_rmtp = redox_timespec::default();
+        } else {
+            redox_rmtp = unsafe { redox_timespec::from(&*rmtp) };
+        }
+        match e(syscall::nanosleep(&redox_rqtp, &mut redox_rmtp)) as c_int {
+            -1 => -1,
+            _ => {
+                unsafe {
+                    if !rmtp.is_null() {
+                        (*rmtp).tv_sec = redox_rmtp.tv_sec;
+                        (*rmtp).tv_nsec = redox_rmtp.tv_nsec as i64;
+                    }
+                }
+                0
+            }
         }
-
-        anonymous_maps().insert(addr as usize, fd);
-        addr as *mut c_void
-    } else {
-        e(syscall::fmap(fildes as usize, off as usize, len as usize)) as *mut c_void
     }
-}
 
-pub unsafe fn munmap(addr: *mut c_void, _len: usize) -> c_int {
-    if e(syscall::funmap(addr as usize)) == !0 {
-        return !0;
+    fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
+        let path = unsafe { c_str(path) };
+        e(syscall::open(path, (oflag as usize) | (mode as usize))) as c_int
     }
-    if let Some(fd) = anonymous_maps().remove(&(addr as usize)) {
-        let _ = syscall::close(fd);
+
+    fn pipe(fds: &mut [c_int]) -> c_int {
+        let mut usize_fds: [usize; 2] = [0; 2];
+        let res = e(syscall::pipe2(&mut usize_fds, 0));
+        fds[0] = usize_fds[0] as c_int;
+        fds[1] = usize_fds[1] as c_int;
+        res as c_int
     }
-    0
-}
 
-pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
-    let redox_rqtp = unsafe { redox_timespec::from(&*rqtp) };
-    let mut redox_rmtp: redox_timespec;
-    if rmtp.is_null() {
-        redox_rmtp = redox_timespec::default();
-    } else {
-        redox_rmtp = unsafe { redox_timespec::from(&*rmtp) };
+    fn read(fd: c_int, buf: &mut [u8]) -> ssize_t {
+        e(syscall::read(fd as usize, buf)) as ssize_t
     }
-    match e(syscall::nanosleep(&redox_rqtp, &mut redox_rmtp)) as c_int {
-        -1 => -1,
-        _ => {
-            unsafe {
-                if !rmtp.is_null() {
-                    (*rmtp).tv_sec = redox_rmtp.tv_sec;
-                    (*rmtp).tv_nsec = redox_rmtp.tv_nsec as i64;
-                }
+
+    fn rename(oldpath: *const c_char, newpath: *const c_char) -> c_int {
+        let (oldpath, newpath) = unsafe { (c_str(oldpath), c_str(newpath)) };
+        match syscall::open(oldpath, O_WRONLY) {
+            Ok(fd) => {
+                let retval = syscall::frename(fd, newpath);
+                let _ = syscall::close(fd);
+                e(retval) as c_int
             }
-            0
+            err => e(err) as c_int,
         }
     }
-}
-
-pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
-    let path = unsafe { c_str(path) };
-    e(syscall::open(path, (oflag as usize) | (mode as usize))) as c_int
-}
 
-pub fn pipe(fds: &mut [c_int]) -> c_int {
-    let mut usize_fds: [usize; 2] = [0; 2];
-    let res = e(syscall::pipe2(&mut usize_fds, 0));
-    fds[0] = usize_fds[0] as c_int;
-    fds[1] = usize_fds[1] as c_int;
-    res as c_int
-}
-
-pub fn raise(sig: c_int) -> c_int {
-    kill(getpid(), sig)
-}
-
-pub fn read(fd: c_int, buf: &mut [u8]) -> ssize_t {
-    e(syscall::read(fd as usize, buf)) as ssize_t
-}
-
-pub unsafe fn recvfrom(
-    socket: c_int,
-    buf: *mut c_void,
-    len: size_t,
-    flags: c_int,
-    address: *mut sockaddr,
-    address_len: *mut socklen_t,
-) -> ssize_t {
-    if flags != 0 {
-        errno = syscall::EOPNOTSUPP;
-        return -1;
-    }
-    if address != ptr::null_mut()
-        && address_len != ptr::null_mut()
-        && getpeername(socket, address, address_len) < 0
-    {
-        return -1;
+    fn rmdir(path: *const c_char) -> c_int {
+        let path = unsafe { c_str(path) };
+        e(syscall::rmdir(path)) as c_int
     }
-    read(socket, slice::from_raw_parts_mut(buf as *mut u8, len))
-}
 
-pub fn rename(oldpath: *const c_char, newpath: *const c_char) -> c_int {
-    let (oldpath, newpath) = unsafe { (c_str(oldpath), c_str(newpath)) };
-    match syscall::open(oldpath, O_WRONLY) {
-        Ok(fd) => {
-            let retval = syscall::frename(fd, newpath);
-            let _ = syscall::close(fd);
-            e(retval) as c_int
+    fn select(
+        nfds: c_int,
+        readfds: *mut fd_set,
+        writefds: *mut fd_set,
+        exceptfds: *mut fd_set,
+        timeout: *mut timeval,
+    ) -> c_int {
+        fn isset(set: *mut fd_set, fd: usize) -> bool {
+            if set.is_null() {
+                return false;
+            }
+
+            let mask = 1 << (fd & (8 * mem::size_of::<c_ulong>() - 1));
+            unsafe { (*set).fds_bits[fd / (8 * mem::size_of::<c_ulong>())] & mask == mask }
         }
-        err => e(err) as c_int,
-    }
-}
 
-pub fn rmdir(path: *const c_char) -> c_int {
-    let path = unsafe { c_str(path) };
-    e(syscall::rmdir(path)) as c_int
-}
+        let event_file = match RawFile::open("event:\0".as_ptr() as *const c_char, 0, 0) {
+            Ok(file) => file,
+            Err(_) => return -1,
+        };
 
-pub fn select(
-    nfds: c_int,
-    readfds: *mut fd_set,
-    writefds: *mut fd_set,
-    exceptfds: *mut fd_set,
-    timeout: *mut timeval,
-) -> c_int {
-    fn isset(set: *mut fd_set, fd: usize) -> bool {
-        if set.is_null() {
-            return false;
+        let mut total = 0;
+
+        for fd in 0..nfds as usize {
+            macro_rules! register {
+                ($fd:expr, $flags:expr) => {
+                    if Self::write(
+                        *event_file,
+                        &syscall::Event {
+                            id: $fd,
+                            flags: $flags,
+                            data: 0,
+                        },
+                    ) < 0
+                    {
+                        return -1;
+                    }
+                };
+            }
+            if isset(readfds, fd) {
+                register!(fd, syscall::EVENT_READ);
+                total += 1;
+            }
+            if isset(writefds, fd) {
+                register!(fd, syscall::EVENT_WRITE);
+                total += 1;
+            }
+            if isset(exceptfds, fd) {
+                total += 1;
+            }
         }
 
-        let mask = 1 << (fd & (8 * mem::size_of::<c_ulong>() - 1));
-        unsafe { (*set).fds_bits[fd / (8 * mem::size_of::<c_ulong>())] & mask == mask }
-    }
+        const TIMEOUT_TOKEN: usize = 1;
 
-    let event_file = match RawFile::open("event:\0".as_ptr() as *const c_char, 0, 0) {
-        Ok(file) => file,
-        Err(_) => return -1,
-    };
-
-    let mut total = 0;
-
-    for fd in 0..nfds as usize {
-        macro_rules! register {
-            ($fd:expr, $flags:expr) => {
-                if write(
-                    *event_file,
-                    &syscall::Event {
-                        id: $fd,
-                        flags: $flags,
-                        data: 0,
-                    },
-                ) < 0
-                {
-                    return -1;
-                }
+        let timeout_file = if timeout.is_null() {
+            None
+        } else {
+            let timeout_file = match RawFile::open(
+                format!("time:{}\0", syscall::CLOCK_MONOTONIC).as_ptr() as *const c_char,
+                0,
+                0,
+            ) {
+                Ok(file) => file,
+                Err(_) => return -1,
             };
-        }
-        if isset(readfds, fd) {
-            register!(fd, syscall::EVENT_READ);
-            total += 1;
-        }
-        if isset(writefds, fd) {
-            register!(fd, syscall::EVENT_WRITE);
-            total += 1;
-        }
-        if isset(exceptfds, fd) {
-            total += 1;
-        }
-    }
-
-    const TIMEOUT_TOKEN: usize = 1;
+            let timeout = unsafe { &*timeout };
+            if Self::write(
+                *timeout_file,
+                &syscall::TimeSpec {
+                    tv_sec: timeout.tv_sec,
+                    tv_nsec: timeout.tv_usec * 1000,
+                },
+            ) < 0
+            {
+                return -1;
+            }
+            if Self::write(
+                *event_file,
+                &syscall::Event {
+                    id: *timeout_file as usize,
+                    flags: syscall::EVENT_READ,
+                    data: TIMEOUT_TOKEN,
+                },
+            ) < 0
+            {
+                return -1;
+            }
 
-    let timeout_file = if timeout.is_null() {
-        None
-    } else {
-        let timeout_file = match RawFile::open(
-            format!("time:{}\0", syscall::CLOCK_MONOTONIC).as_ptr() as *const c_char,
-            0,
-            0,
-        ) {
-            Ok(file) => file,
-            Err(_) => return -1,
+            Some(timeout_file)
         };
-        let timeout = unsafe { &*timeout };
-        if write(
-            *timeout_file,
-            &syscall::TimeSpec {
-                tv_sec: timeout.tv_sec,
-                tv_nsec: timeout.tv_usec * 1000,
-            },
-        ) < 0
-        {
-            return -1;
-        }
-        if write(
-            *event_file,
-            &syscall::Event {
-                id: *timeout_file as usize,
-                flags: syscall::EVENT_READ,
-                data: TIMEOUT_TOKEN,
-            },
-        ) < 0
-        {
+
+        let mut event = syscall::Event::default();
+        if Self::read(*event_file, &mut event) < 0 {
             return -1;
         }
 
-        Some(timeout_file)
-    };
+        if timeout_file.is_some() && event.data == TIMEOUT_TOKEN {
+            return 0;
+        }
 
-    let mut event = syscall::Event::default();
-    if read(*event_file, &mut event) < 0 {
-        return -1;
+        // I really don't get why, but select wants me to return the total number
+        // of file descriptors that was inputted. I'm confused.
+        total
     }
 
-    if timeout_file.is_some() && event.data == TIMEOUT_TOKEN {
-        return 0;
+    fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
+        e(syscall::setpgid(pid as usize, pgid as usize)) as c_int
     }
 
-    // I really don't get why, but select wants me to return the total number
-    // of file descriptors that was inputted. I'm confused.
-    total
-}
-
-pub unsafe fn sendto(
-    socket: c_int,
-    buf: *const c_void,
-    len: size_t,
-    flags: c_int,
-    dest_addr: *const sockaddr,
-    dest_len: socklen_t,
-) -> ssize_t {
-    if dest_addr != ptr::null() || dest_len != 0 {
-        errno = syscall::EISCONN;
-        return -1;
-    }
-    if flags != 0 {
-        errno = syscall::EOPNOTSUPP;
-        return -1;
+    fn setregid(rgid: gid_t, egid: gid_t) -> c_int {
+        e(syscall::setregid(rgid as usize, egid as usize)) as c_int
     }
-    write(socket, slice::from_raw_parts(buf as *const u8, len))
-}
 
-pub fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
-    let _ = writeln!(
-        FileWriter(2),
-        "unimplemented: setitimer({}, {:p}, {:p})",
-        which,
-        new,
-        old
-    );
-
-    unsafe {
-        *old = itimerval::default();
+    fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
+        e(syscall::setreuid(ruid as usize, euid as usize)) as c_int
     }
-    0
-}
-
-pub fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
-    e(syscall::setpgid(pid as usize, pgid as usize)) as c_int
-}
 
-pub fn setregid(rgid: gid_t, egid: gid_t) -> c_int {
-    e(syscall::setregid(rgid as usize, egid as usize)) as c_int
-}
-
-pub fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
-    e(syscall::setreuid(ruid as usize, euid as usize)) as c_int
-}
-
-pub fn setsockopt(
-    socket: c_int,
-    level: c_int,
-    option_name: c_int,
-    option_value: *const c_void,
-    option_len: socklen_t,
-) -> c_int {
-    let _ = writeln!(
-        FileWriter(2),
-        "unimplemented: setsockopt({}, {}, {}, {:p}, {})",
-        socket,
-        level,
-        option_name,
-        option_value,
-        option_len
-    );
-    -1
-}
-
-pub fn shutdown(socket: c_int, how: c_int) -> c_int {
-    let _ = writeln!(
-        FileWriter(2),
-        "unimplemented: shutdown({}, {})",
-        socket,
-        how
-    );
-    -1
-}
-
-pub unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
-    if !oact.is_null() {
-        // Assumes the last sigaction() call was made by relibc and not a different one
-        if SIG_HANDLER.is_some() {
-            (*oact).sa_handler = SIG_HANDLER;
+    fn stat(path: *const c_char, buf: *mut stat) -> c_int {
+        let path = unsafe { c_str(path) };
+        match syscall::open(path, O_STAT) {
+            Err(err) => e(Err(err)) as c_int,
+            Ok(fd) => {
+                let res = Self::fstat(fd as i32, buf);
+                let _ = syscall::close(fd);
+                res
+            }
         }
     }
-    let act = if act.is_null() {
-        None
-    } else {
-        SIG_HANDLER = (*act).sa_handler;
-        let m = (*act).sa_mask;
-        Some(syscall::SigAction {
-            sa_handler: sig_handler,
-            sa_mask: [0, m as u64],
-            sa_flags: (*act).sa_flags as usize,
-        })
-    };
-    let mut old = syscall::SigAction::default();
-    let ret = e(syscall::sigaction(
-        sig as usize,
-        act.as_ref(),
-        if oact.is_null() { None } else { Some(&mut old) },
-    )) as c_int;
-    if !oact.is_null() {
-        let m = old.sa_mask;
-        (*oact).sa_mask = m[1] as c_ulong;
-        (*oact).sa_flags = old.sa_flags as c_ulong;
-    }
-    ret
-}
 
-pub fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
-    let _ = writeln!(
-        FileWriter(2),
-        "unimplemented: sigprocmask({}, {:p}, {:p})",
-        how,
-        set,
-        oset
-    );
-    -1
-}
-
-pub fn stat(path: *const c_char, buf: *mut stat) -> c_int {
-    let path = unsafe { c_str(path) };
-    match syscall::open(path, O_STAT) {
-        Err(err) => e(Err(err)) as c_int,
-        Ok(fd) => {
-            let res = fstat(fd as i32, buf);
-            let _ = syscall::close(fd);
-            res
+    fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
+        let dup = e(syscall::dup(fd as usize, b"termios"));
+        if dup == !0 {
+            return -1;
         }
-    }
-}
 
-pub unsafe fn socket(domain: c_int, mut kind: c_int, protocol: c_int) -> c_int {
-    if domain != AF_INET {
-        errno = syscall::EAFNOSUPPORT;
-        return -1;
-    }
-    if protocol != 0 {
-        errno = syscall::EPROTONOSUPPORT;
-        return -1;
-    }
+        let read = e(syscall::read(dup, unsafe { slice::from_raw_parts_mut(
+            out as *mut u8,
+            mem::size_of::<termios>()
+        ) }));
+        let _ = syscall::close(dup);
 
-    let mut flags = O_RDWR;
-    if kind & SOCK_NONBLOCK == SOCK_NONBLOCK {
-        kind &= !SOCK_NONBLOCK;
-        flags |= O_NONBLOCK;
-    }
-    if kind & SOCK_CLOEXEC == SOCK_CLOEXEC {
-        kind &= !SOCK_CLOEXEC;
-        flags |= O_CLOEXEC;
-    }
-
-    // The tcp: and udp: schemes allow using no path,
-    // and later specifying one using `dup`.
-    match kind {
-        SOCK_STREAM => e(syscall::open("tcp:", flags)) as c_int,
-        SOCK_DGRAM => e(syscall::open("udp:", flags)) as c_int,
-        _ => {
-            errno = syscall::EPROTOTYPE;
-            -1
+        if read == !0 {
+            return -1;
         }
-    }
-}
-
-pub fn socketpair(domain: c_int, kind: c_int, protocol: c_int, socket_vector: *mut c_int) -> c_int {
-    let _ = writeln!(
-        FileWriter(2),
-        "unimplemented: socketpair({}, {}, {}, {:p})",
-        domain,
-        kind,
-        protocol,
-        socket_vector
-    );
-    -1
-}
-
-pub fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
-    let dup = e(syscall::dup(fd as usize, b"termios"));
-    if dup == !0 {
-        return -1;
+        0
     }
 
-    let read = e(syscall::read(dup, unsafe { slice::from_raw_parts_mut(
-        out as *mut u8,
-        mem::size_of::<termios>()
-    ) }));
-    let _ = syscall::close(dup);
+    fn tcsetattr(fd: c_int, _act: c_int, value: *const termios) -> c_int {
+        let dup = e(syscall::dup(fd as usize, b"termios"));
+        if dup == !0 {
+            return -1;
+        }
 
-    if read == !0 {
-        return -1;
-    }
-    0
-}
+        let write = e(syscall::write(dup, unsafe { slice::from_raw_parts(
+            value as *const u8,
+            mem::size_of::<termios>()
+        ) }));
+        let _ = syscall::close(dup);
 
-pub fn tcsetattr(fd: c_int, _act: c_int, value: *const termios) -> c_int {
-    let dup = e(syscall::dup(fd as usize, b"termios"));
-    if dup == !0 {
-        return -1;
+        if write == !0 {
+            return -1;
+        }
+        0
     }
 
-    let write = e(syscall::write(dup, unsafe { slice::from_raw_parts(
-        value as *const u8,
-        mem::size_of::<termios>()
-    ) }));
-    let _ = syscall::close(dup);
-
-    if write == !0 {
-        return -1;
+    fn unlink(path: *const c_char) -> c_int {
+        let path = unsafe { c_str(path) };
+        e(syscall::unlink(path)) as c_int
     }
-    0
-}
 
-pub fn times(out: *mut tms) -> clock_t {
-    let _ = writeln!(FileWriter(2), "unimplemented: times({:p})", out);
-    !0
-}
-
-pub fn umask(mask: mode_t) -> mode_t {
-    let _ = writeln!(FileWriter(2), "unimplemented: umask({})", mask);
-    0
-}
-
-pub fn unlink(path: *const c_char) -> c_int {
-    let path = unsafe { c_str(path) };
-    e(syscall::unlink(path)) as c_int
-}
-
-pub fn waitpid(mut pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t {
-    if pid == !0 {
-        pid = 0;
-    }
-    unsafe {
-        let mut temp: usize = 0;
-        let res = e(syscall::waitpid(pid as usize, &mut temp, options as usize));
-        if !stat_loc.is_null() {
-            *stat_loc = temp as c_int;
+    fn waitpid(mut pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t {
+        if pid == !0 {
+            pid = 0;
+        }
+        unsafe {
+            let mut temp: usize = 0;
+            let res = e(syscall::waitpid(pid as usize, &mut temp, options as usize));
+            if !stat_loc.is_null() {
+                *stat_loc = temp as c_int;
+            }
+            res as pid_t
         }
-        res as pid_t
     }
-}
 
-pub fn write(fd: c_int, buf: &[u8]) -> ssize_t {
-    e(syscall::write(fd as usize, buf)) as ssize_t
-}
-
-pub fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int {
-    let mut redox_tp = unsafe { redox_timespec::from(&*tp) };
-    match e(syscall::clock_gettime(clk_id as usize, &mut redox_tp)) as c_int {
-        -1 => -1,
-        _ => {
-            unsafe {
-                (*tp).tv_sec = redox_tp.tv_sec;
-                (*tp).tv_nsec = redox_tp.tv_nsec as i64;
-            };
-            0
-        }
+    fn write(fd: c_int, buf: &[u8]) -> ssize_t {
+        e(syscall::write(fd as usize, buf)) as ssize_t
     }
 }
diff --git a/src/platform/src/redox/signal.rs b/src/platform/src/redox/signal.rs
new file mode 100644
index 0000000000000000000000000000000000000000..2c80345f8575ab001b5610252bbfc0bb7a721101
--- /dev/null
+++ b/src/platform/src/redox/signal.rs
@@ -0,0 +1,47 @@
+impl PalSignal for Sys {
+    fn kill(pid: pid_t, sig: c_int) -> c_int {
+        e(syscall::kill(pid as usize, sig as usize)) as c_int
+    }
+
+    fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
+        e(syscall::kill(-(pgrp as isize) as usize, sig as usize)) as c_int
+    }
+
+    fn raise(sig: c_int) -> c_int {
+        kill(getpid(), sig)
+    }
+
+    unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
+        if !oact.is_null() {
+            // Assumes the last sigaction() call was made by relibc and not a different one
+            if SIG_HANDLER.is_some() {
+                (*oact).sa_handler = SIG_HANDLER;
+            }
+        }
+        let act = if act.is_null() {
+            None
+        } else {
+            SIG_HANDLER = (*act).sa_handler;
+            let m = (*act).sa_mask;
+            Some(syscall::SigAction {
+                sa_handler: sig_handler,
+                sa_mask: [0, m as u64],
+                sa_flags: (*act).sa_flags as usize,
+            })
+        };
+        let mut old = syscall::SigAction::default();
+        let ret = e(syscall::sigaction(
+            sig as usize,
+            act.as_ref(),
+            if oact.is_null() { None } else { Some(&mut old) },
+        )) as c_int;
+        if !oact.is_null() {
+            let m = old.sa_mask;
+            (*oact).sa_mask = m[1] as c_ulong;
+            (*oact).sa_flags = old.sa_flags as c_ulong;
+        }
+        ret
+    }
+
+    //fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int;
+}
diff --git a/src/platform/src/redox/socket.rs b/src/platform/src/redox/socket.rs
new file mode 100644
index 0000000000000000000000000000000000000000..6437eeb0492cf07fd0372a769a625f25204ffcd5
--- /dev/null
+++ b/src/platform/src/redox/socket.rs
@@ -0,0 +1,180 @@
+macro_rules! bind_or_connect {
+    (bind $path:expr) => {
+        concat!("/", $path)
+    };
+    (connect $path:expr) => {
+        $path
+    };
+    ($mode:ident $socket:expr, $address:expr, $address_len:expr) => {{
+        if (*$address).sa_family as c_int != AF_INET {
+            errno = syscall::EAFNOSUPPORT;
+            return -1;
+        }
+        if ($address_len as usize) < mem::size_of::<sockaddr>() {
+            errno = syscall::EINVAL;
+            return -1;
+        }
+        let data = &*($address as *const sockaddr_in);
+        let addr = &data.sin_addr.s_addr;
+        let port = in_port_t::from_be(data.sin_port); // This is transmuted from bytes in BigEndian order
+        let path = format!(bind_or_connect!($mode "{}.{}.{}.{}:{}"), addr[0], addr[1], addr[2], addr[3], port);
+
+        // Duplicate the socket, and then duplicate the copy back to the original fd
+        let fd = e(syscall::dup($socket as usize, path.as_bytes()));
+        if (fd as c_int) < 0 {
+            return -1;
+        }
+        let result = syscall::dup2(fd, $socket as usize, &[]);
+        let _ = syscall::close(fd);
+        if (e(result) as c_int) < 0 {
+            return -1;
+        }
+        0
+    }}
+}
+
+unsafe fn inner_get_name(
+    local: bool,
+    socket: c_int,
+    address: *mut sockaddr,
+    address_len: *mut socklen_t,
+) -> Result<usize> {
+    // 32 should probably be large enough.
+    // Format: tcp:remote/local
+    // and since we only yet support IPv4 (I think)...
+    let mut buf = [0; 32];
+    let len = syscall::fpath(socket as usize, &mut buf)?;
+    let buf = &buf[..len];
+    assert!(&buf[..4] == b"tcp:" || &buf[..4] == b"udp:");
+    let buf = &buf[4..];
+
+    let mut parts = buf.split(|c| *c == b'/');
+    if local {
+        // Skip the remote part
+        parts.next();
+    }
+    let part = parts.next().expect("Invalid reply from netstack");
+
+    let data = slice::from_raw_parts_mut(
+        &mut (*address).data as *mut _ as *mut u8,
+        (*address).data.len(),
+    );
+
+    let len = data.len().min(part.len());
+    data[..len].copy_from_slice(&part[..len]);
+
+    *address_len = len as socklen_t;
+    Ok(0)
+}
+
+impl PalSocket for Sys {
+    unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
+        let stream = e(syscall::dup(socket as usize, b"listen")) as c_int;
+        if stream < 0 {
+            return -1;
+        }
+        if address != ptr::null_mut()
+            && address_len != ptr::null_mut()
+            && getpeername(stream, address, address_len) < 0
+        {
+            return -1;
+        }
+        stream
+    }
+
+    unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
+        bind_or_connect!(bind socket, address, address_len)
+    }
+
+    unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
+        bind_or_connect!(connect socket, address, address_len)
+    }
+
+    unsafe fn getpeername(
+        socket: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> c_int {
+        e(inner_get_name(false, socket, address, address_len)) as c_int
+    }
+
+    unsafe fn getsockname(
+        socket: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> c_int {
+        e(inner_get_name(true, socket, address, address_len)) as c_int
+    }
+
+    unsafe fn recvfrom(
+        socket: c_int,
+        buf: *mut c_void,
+        len: size_t,
+        flags: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> ssize_t {
+        if flags != 0 {
+            errno = syscall::EOPNOTSUPP;
+            return -1;
+        }
+        if address != ptr::null_mut()
+            && address_len != ptr::null_mut()
+            && getpeername(socket, address, address_len) < 0
+        {
+            return -1;
+        }
+        read(socket, slice::from_raw_parts_mut(buf as *mut u8, len))
+    }
+
+    unsafe fn sendto(
+        socket: c_int,
+        buf: *const c_void,
+        len: size_t,
+        flags: c_int,
+        dest_addr: *const sockaddr,
+        dest_len: socklen_t,
+    ) -> ssize_t {
+        if dest_addr != ptr::null() || dest_len != 0 {
+            errno = syscall::EISCONN;
+            return -1;
+        }
+        if flags != 0 {
+            errno = syscall::EOPNOTSUPP;
+            return -1;
+        }
+        write(socket, slice::from_raw_parts(buf as *const u8, len))
+    }
+
+    unsafe fn socket(domain: c_int, mut kind: c_int, protocol: c_int) -> c_int {
+        if domain != AF_INET {
+            errno = syscall::EAFNOSUPPORT;
+            return -1;
+        }
+        if protocol != 0 {
+            errno = syscall::EPROTONOSUPPORT;
+            return -1;
+        }
+
+        let mut flags = O_RDWR;
+        if kind & SOCK_NONBLOCK == SOCK_NONBLOCK {
+            kind &= !SOCK_NONBLOCK;
+            flags |= O_NONBLOCK;
+        }
+        if kind & SOCK_CLOEXEC == SOCK_CLOEXEC {
+            kind &= !SOCK_CLOEXEC;
+            flags |= O_CLOEXEC;
+        }
+
+        // The tcp: and udp: schemes allow using no path,
+        // and later specifying one using `dup`.
+        match kind {
+            SOCK_STREAM => e(syscall::open("tcp:", flags)) as c_int,
+            SOCK_DGRAM => e(syscall::open("udp:", flags)) as c_int,
+            _ => {
+                errno = syscall::EPROTOTYPE;
+                -1
+            }
+        }
+    }
+}