diff --git a/Makefile b/Makefile index bb0f7c15b..1aca47401 100644 --- a/Makefile +++ b/Makefile @@ -423,6 +423,7 @@ drivers: \ coreutils: \ filesystem/bin/basename \ filesystem/bin/cat \ + filesystem/bin/chmod \ filesystem/bin/clear \ filesystem/bin/cp \ filesystem/bin/cut \ diff --git a/kernel/scheme/user.rs b/kernel/scheme/user.rs index 3a8c4af10..da1950081 100644 --- a/kernel/scheme/user.rs +++ b/kernel/scheme/user.rs @@ -231,6 +231,14 @@ impl Scheme for UserScheme { result } + fn chmod(&self, path: &[u8], mode: u16, _uid: u32, _gid: u32) -> Result { + let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; + let address = inner.capture(path)?; + let result = inner.call(SYS_CHMOD, address, path.len(), mode as usize); + let _ = inner.release(address); + result + } + fn rmdir(&self, path: &[u8], _uid: u32, _gid: u32) -> Result { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; let address = inner.capture(path)?; diff --git a/kernel/syscall/fs.rs b/kernel/syscall/fs.rs index c12dc89d8..b10a34a42 100644 --- a/kernel/syscall/fs.rs +++ b/kernel/syscall/fs.rs @@ -166,6 +166,28 @@ pub fn mkdir(path: &[u8], mode: u16) -> Result { scheme.mkdir(reference_opt.unwrap_or(b""), mode, uid, gid) } +/// chmod syscall +pub fn chmod(path: &[u8], mode: u16) -> Result { + let (path_canon, uid, gid) = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + (context.canonicalize(path), context.euid, context.egid) + }; + + 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(ENODEV))?; + let scheme = { + let schemes = scheme::schemes(); + let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENODEV))?; + scheme.clone() + }; + scheme.chmod(reference_opt.unwrap_or(b""), mode, uid, gid) +} + /// rmdir syscall pub fn rmdir(path: &[u8]) -> Result { let (path_canon, uid, gid) = { diff --git a/kernel/syscall/mod.rs b/kernel/syscall/mod.rs index b34df1d3f..89058df11 100644 --- a/kernel/syscall/mod.rs +++ b/kernel/syscall/mod.rs @@ -54,6 +54,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize SYS_CLASS_PATH => match a { SYS_OPEN => open(validate_slice(b as *const u8, c)?, d).map(FileHandle::into), SYS_MKDIR => mkdir(validate_slice(b as *const u8, c)?, d as u16), + SYS_CHMOD => chmod(validate_slice(b as *const u8, c)?, d as u16), SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?), SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?), _ => unreachable!() diff --git a/libstd_real/libc/src/syscall.rs b/libstd_real/libc/src/syscall.rs index 60e358972..260d0306b 100644 --- a/libstd_real/libc/src/syscall.rs +++ b/libstd_real/libc/src/syscall.rs @@ -9,7 +9,7 @@ pub use self::syscall::error::*; pub use self::syscall::flag::*; pub use self::syscall::{ clock_gettime, clone, execve as exec, exit, futex, getpid, kill, nanosleep, setgid, setuid, waitpid, - chdir, getcwd, open, mkdir, rmdir, unlink, dup, pipe2, + chdir, chmod, getcwd, open, mkdir, rmdir, unlink, dup, pipe2, read, write, fcntl, fpath, fstat, fsync, ftruncate, lseek, close }; diff --git a/programs/coreutils b/programs/coreutils index 9c513b8fa..00872fb34 160000 --- a/programs/coreutils +++ b/programs/coreutils @@ -1 +1 @@ -Subproject commit 9c513b8faa3165d60ebdf553a5a7d01ad1c5b316 +Subproject commit 00872fb3437a3e91568519fe34597c517f1f009d diff --git a/programs/orbutils b/programs/orbutils index 81bde2c54..55f2838c1 160000 --- a/programs/orbutils +++ b/programs/orbutils @@ -1 +1 @@ -Subproject commit 81bde2c5484eb8d2345194a60f8fd556f2c54853 +Subproject commit 55f2838c1bd86648b2ca52afd2d1d2b3c4efdf5f diff --git a/programs/userutils b/programs/userutils index 6305f222a..d44639145 160000 --- a/programs/userutils +++ b/programs/userutils @@ -1 +1 @@ -Subproject commit 6305f222ad6c1b00fce6930b7df5cb2a659df8b4 +Subproject commit d44639145bbadeae57066aecaec146f7d3e8c645 diff --git a/rust b/rust index 2e5c82161..267bc54fb 160000 --- a/rust +++ b/rust @@ -1 +1 @@ -Subproject commit 2e5c821619c7b62ec46c8a4f90ead4e59fb6c36e +Subproject commit 267bc54fbd2cfeadde7a87fc2aa3fb975ff58b6c diff --git a/schemes/redoxfs b/schemes/redoxfs index 8a22d9666..31605167c 160000 --- a/schemes/redoxfs +++ b/schemes/redoxfs @@ -1 +1 @@ -Subproject commit 8a22d9666927cd2d7040711b7db4eb4dcf73fc48 +Subproject commit 31605167ceb20bc3e2ffb6ef0b15fc05ca16ad7c diff --git a/syscall b/syscall index cd6f7c219..3e39d46f9 160000 --- a/syscall +++ b/syscall @@ -1 +1 @@ -Subproject commit cd6f7c219cc295e9d0b9f5068b107fd13f12af90 +Subproject commit 3e39d46f969a0576120994ea13530e5712773cf5