diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs
index 3483477d40cf6..2e2216186f1e6 100644
--- a/src/libstd/sys/redox/fs.rs
+++ b/src/libstd/sys/redox/fs.rs
@@ -384,8 +384,11 @@ pub fn unlink(p: &Path) -> io::Result<()> {
 }
 
 pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
-    copy(old, new)?;
-    unlink(old)?;
+    let fd = cvt(syscall::open(old.to_str().unwrap(),
+                               syscall::O_CLOEXEC | syscall::O_STAT | syscall::O_NOFOLLOW))?;
+    let res = cvt(syscall::frename(fd, new.to_str().unwrap()));
+    cvt(syscall::close(fd))?;
+    res?;
     Ok(())
 }
 
@@ -421,18 +424,22 @@ fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
 }
 
 pub fn readlink(p: &Path) -> io::Result<PathBuf> {
-    let fd = cvt(syscall::open(p.to_str().unwrap(), syscall::O_SYMLINK | syscall::O_RDONLY))?;
+    let fd = cvt(syscall::open(p.to_str().unwrap(),
+                               syscall::O_CLOEXEC | syscall::O_SYMLINK | syscall::O_RDONLY))?;
     let mut buf: [u8; 4096] = [0; 4096];
-    let count = cvt(syscall::read(fd, &mut buf))?;
+    let res = cvt(syscall::read(fd, &mut buf));
     cvt(syscall::close(fd))?;
+    let count = res?;
     Ok(PathBuf::from(unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) }))
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
     let fd = cvt(syscall::open(dst.to_str().unwrap(),
-                               syscall::O_SYMLINK | syscall::O_CREAT | syscall::O_WRONLY | 0o777))?;
-    cvt(syscall::write(fd, src.to_str().unwrap().as_bytes()))?;
+                               syscall::O_CLOEXEC | syscall::O_SYMLINK |
+                               syscall::O_CREAT | syscall::O_WRONLY | 0o777))?;
+    let res = cvt(syscall::write(fd, src.to_str().unwrap().as_bytes()));
     cvt(syscall::close(fd))?;
+    res?;
     Ok(())
 }
 
diff --git a/src/libstd/sys/redox/syscall/call.rs b/src/libstd/sys/redox/syscall/call.rs
index 7770a2f3f1b5a..f9a8bd61ac800 100644
--- a/src/libstd/sys/redox/syscall/call.rs
+++ b/src/libstd/sys/redox/syscall/call.rs
@@ -93,7 +93,19 @@ pub fn exit(status: usize) -> Result<usize> {
     unsafe { syscall1(SYS_EXIT, status) }
 }
 
-/// Register a file for event-based I/O
+/// Change file permissions
+pub fn fchmod(fd: usize, mode: u16) -> Result<usize> {
+    unsafe { syscall2(SYS_FCHMOD, fd, mode as usize) }
+
+}
+
+/// Change file ownership
+pub fn fchown(fd: usize, uid: u32, gid: u32) -> Result<usize> {
+    unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) }
+
+}
+
+/// Change file descriptor flags
 pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result<usize> {
     unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) }
 }
@@ -118,6 +130,11 @@ pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
     unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) }
 }
 
+/// Rename a file
+pub fn frename<T: AsRef<[u8]>>(fd: usize, path: T) -> Result<usize> {
+    unsafe { syscall3(SYS_FRENAME, fd, path.as_ref().as_ptr() as usize, path.as_ref().len()) }
+}
+
 /// Get metadata about a file
 pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
     unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::<Stat>()) }
diff --git a/src/libstd/sys/redox/syscall/number.rs b/src/libstd/sys/redox/syscall/number.rs
index 07db91647ff68..45cb40e390840 100644
--- a/src/libstd/sys/redox/syscall/number.rs
+++ b/src/libstd/sys/redox/syscall/number.rs
@@ -32,11 +32,14 @@ pub const SYS_DUP2: usize =     SYS_CLASS_FILE | SYS_RET_FILE | 63;
 pub const SYS_READ: usize =     SYS_CLASS_FILE | SYS_ARG_MSLICE | 3;
 pub const SYS_WRITE: usize =    SYS_CLASS_FILE | SYS_ARG_SLICE | 4;
 pub const SYS_LSEEK: usize =    SYS_CLASS_FILE | 19;
+pub const SYS_FCHMOD: usize =   SYS_CLASS_FILE | 94;
+pub const SYS_FCHOWN: usize =   SYS_CLASS_FILE | 207;
 pub const SYS_FCNTL: usize =    SYS_CLASS_FILE | 55;
 pub const SYS_FEVENT: usize =   SYS_CLASS_FILE | 927;
 pub const SYS_FMAP: usize =     SYS_CLASS_FILE | 90;
 pub const SYS_FUNMAP: usize =   SYS_CLASS_FILE | 91;
 pub const SYS_FPATH: usize =    SYS_CLASS_FILE | SYS_ARG_MSLICE | 928;
+pub const SYS_FRENAME: usize =  SYS_CLASS_FILE | SYS_ARG_PATH | 38;
 pub const SYS_FSTAT: usize =    SYS_CLASS_FILE | SYS_ARG_MSLICE | 28;
 pub const SYS_FSTATVFS: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 100;
 pub const SYS_FSYNC: usize =    SYS_CLASS_FILE | 118;