From 62d151c9e8b51017319bc8bc63c783f45647112d Mon Sep 17 00:00:00 2001
From: Jeremy Soller <jackpot51@gmail.com>
Date: Wed, 28 Sep 2016 11:18:28 -0600
Subject: [PATCH] Unlink syscall

---
 scheme/user.rs | 24 ++++++++++++++++++++++++
 syscall/fs.rs  | 22 ++++++++++++++++++++++
 syscall/mod.rs |  9 ++++++++-
 3 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/scheme/user.rs b/scheme/user.rs
index e91fb097..dd415cc1 100644
--- a/scheme/user.rs
+++ b/scheme/user.rs
@@ -216,6 +216,30 @@ impl Scheme for UserScheme {
         result
     }
 
+    fn mkdir(&self, path: &[u8], mode: usize) -> Result<usize> {
+        let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
+        let address = inner.capture(path)?;
+        let result = inner.call(SYS_MKDIR, address, path.len(), mode);
+        let _ = inner.release(address);
+        result
+    }
+
+    fn rmdir(&self, path: &[u8]) -> Result<usize> {
+        let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
+        let address = inner.capture(path)?;
+        let result = inner.call(SYS_RMDIR, address, path.len(), 0);
+        let _ = inner.release(address);
+        result
+    }
+
+    fn unlink(&self, path: &[u8]) -> Result<usize> {
+        let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
+        let address = inner.capture(path)?;
+        let result = inner.call(SYS_UNLINK, address, path.len(), 0);
+        let _ = inner.release(address);
+        result
+    }
+
     fn dup(&self, file: usize) -> Result<usize> {
         let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
         inner.call(SYS_DUP, file, 0, 0)
diff --git a/syscall/fs.rs b/syscall/fs.rs
index 91c36e49..20e6c92d 100644
--- a/syscall/fs.rs
+++ b/syscall/fs.rs
@@ -62,6 +62,28 @@ pub fn open(path: &[u8], flags: usize) -> Result<usize> {
     }).ok_or(Error::new(EMFILE))
 }
 
+/// Unlink syscall
+pub fn unlink(path: &[u8]) -> Result<usize> {
+    let path_canon = {
+        let contexts = context::contexts();
+        let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
+        let context = context_lock.read();
+        context.canonicalize(path)
+    };
+
+    let mut parts = path_canon.splitn(2, |&b| b == b':');
+    let namespace_opt = parts.next();
+    let reference_opt = parts.next();
+
+    let namespace = namespace_opt.ok_or(Error::new(ENOENT))?;
+    let scheme = {
+        let schemes = scheme::schemes();
+        let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?;
+        scheme.clone()
+    };
+    scheme.unlink(reference_opt.unwrap_or(b""))
+}
+
 /// Close syscall
 pub fn close(fd: usize) -> Result<usize> {
     let file = {
diff --git a/syscall/mod.rs b/syscall/mod.rs
index 2815091d..9592917d 100644
--- a/syscall/mod.rs
+++ b/syscall/mod.rs
@@ -32,6 +32,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
             SYS_OPEN => open(validate_slice(b as *const u8, c)?, d),
             SYS_CLOSE => close(b),
             SYS_WAITPID => waitpid(b, c, d),
+            SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?),
             SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
             SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
             SYS_LSEEK => lseek(b, c, d),
@@ -59,5 +60,11 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
         }
     }
 
-    Error::mux(inner(a, b, c, d, e, f, stack))
+    let result = inner(a, b, c, d, e, f, stack);
+
+    if let Err(ref err) = result {
+        println!("{}, {}, {}, {}: {}", a, b, c, d, err);
+    }
+
+    Error::mux(result)
 }
-- 
GitLab