From 31605167ceb20bc3e2ffb6ef0b15fc05ca16ad7c Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Tue, 15 Nov 2016 17:07:37 -0700 Subject: [PATCH] Add chmod --- scheme/resource.rs | 2 +- scheme/scheme.rs | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/scheme/resource.rs b/scheme/resource.rs index ea044d2..f985092 100644 --- a/scheme/resource.rs +++ b/scheme/resource.rs @@ -178,7 +178,7 @@ impl Resource for FileResource { F_SETFL => { self.flags = arg & ! O_ACCMODE; Ok(0) - } + }, _ => Err(Error::new(EINVAL)) } } diff --git a/scheme/scheme.rs b/scheme/scheme.rs index a87c2b7..c6ff37b 100644 --- a/scheme/scheme.rs +++ b/scheme/scheme.rs @@ -9,7 +9,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use syscall::data::Stat; use syscall::error::{Error, Result, EACCES, EEXIST, EISDIR, ENOTDIR, EPERM, ENOENT, EBADF}; -use syscall::flag::{O_CREAT, O_TRUNC, O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR}; +use syscall::flag::{O_CREAT, O_TRUNC, O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, MODE_PERM}; use syscall::scheme::Scheme; pub struct FileScheme { @@ -196,6 +196,35 @@ impl Scheme for FileScheme { } } + fn chmod(&self, url: &[u8], mode: u16, uid: u32, gid: u32) -> Result<usize> { + let path = str::from_utf8(url).unwrap_or("").trim_matches('/'); + + // println!("Chmod '{}'", path); + + let mut fs = self.fs.borrow_mut(); + + let mut nodes = Vec::new(); + let node_result = fs.path_nodes(path, &mut nodes); + for node in nodes.iter() { + if ! node.1.permission(uid, gid, Node::MODE_EXEC) { + // println!("dir not executable {:o}", node.1.mode); + return Err(Error::new(EACCES)); + } + if ! node.1.is_dir() { + return Err(Error::new(ENOTDIR)); + } + } + + let mut node = node_result?; + if node.1.uid == uid || uid == 0 { + node.1.mode = (node.1.mode & ! MODE_PERM) | (mode & MODE_PERM); + try!(fs.write_at(node.0, &node.1)); + Ok(0) + } else { + Err(Error::new(EPERM)) + } + } + fn rmdir(&self, url: &[u8], uid: u32, gid: u32) -> Result<usize> { let path = str::from_utf8(url).unwrap_or("").trim_matches('/'); -- GitLab