diff --git a/Cargo.lock b/Cargo.lock index 2003e81b2eeae80d860018e381165f07491cdd15..efb0e69a1083de5e6dbbf5a02ad6f97adc121838 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,13 +32,13 @@ dependencies = [ [[package]] name = "kernel" -version = "0.1.32" +version = "0.1.33" dependencies = [ "alloc_kernel 0.1.0", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "raw-cpuid 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.32", + "redox_syscall 0.1.33", "spin 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "x86 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -75,7 +75,7 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.32" +version = "0.1.33" [[package]] name = "scroll" diff --git a/Cargo.toml b/Cargo.toml index 2f066eb3bbbd29f8aa7ed56575c62e1b062237cd..3cee8c964cb9ebe927c6a58d4d0090dac222bd6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kernel" -version = "0.1.32" +version = "0.1.33" build = "build.rs" [lib] diff --git a/src/scheme/user.rs b/src/scheme/user.rs index 31b69beda5c2bfc957f87933a1116986c398b65e..8ceb28439dc467bd932b5f1c6a1c66f3b633db4f 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -334,6 +334,14 @@ impl Scheme for UserScheme { result } + fn frename(&self, file: usize, path: &[u8], _uid: u32, _gid: u32) -> Result<usize> { + let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; + let address = inner.capture(path)?; + let result = inner.call(SYS_FRENAME, file, address, path.len()); + let _ = inner.release(address); + result + } + fn fstat(&self, file: usize, stat: &mut Stat) -> Result<usize> { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; let address = inner.capture_mut(stat)?; diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 168d165cebd9a9303b402489b141e6e9ffa0e50b..6cd747a1d2aa50607b9fe957c9299f6b90e547c1 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -422,6 +422,42 @@ pub fn fevent(fd: FileHandle, flags: usize) -> Result<usize> { Ok(0) } +pub fn frename(fd: FileHandle, path: &[u8]) -> Result<usize> { + let file = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + let file = context.get_file(fd).ok_or(Error::new(EBADF))?; + file + }; + + let (path_canon, uid, gid, scheme_ns) = { + 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, context.ens) + }; + + let mut parts = path_canon.splitn(2, |&b| b == b':'); + let scheme_name_opt = parts.next(); + let reference_opt = parts.next(); + + let scheme_name = scheme_name_opt.ok_or(Error::new(ENODEV))?; + let (scheme_id, scheme) = { + let schemes = scheme::schemes(); + let (scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?; + (scheme_id, scheme.clone()) + }; + + let description = file.description.read(); + + if scheme_id == description.scheme { + scheme.frename(description.number, reference_opt.unwrap_or(b""), uid, gid) + } else { + Err(Error::new(EXDEV)) + } +} + pub fn funmap(virtual_address: usize) -> Result<usize> { if virtual_address == 0 { Ok(0) diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index 793f23b22d41beaf496d6649eebd8210d5258f19..d0ff5f32ec1058aaaec69c7e7960a7f67baf4c75 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -64,6 +64,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize SYS_DUP2 => dup2(fd, FileHandle::from(c), validate_slice(d as *const u8, e)?).map(FileHandle::into), SYS_FCNTL => fcntl(fd, c, d), SYS_FEVENT => fevent(fd, c), + SYS_FRENAME => frename(fd, validate_slice(c as *const u8, d)?), SYS_FUNMAP => funmap(b), _ => file_op(a, fd, c, d) } diff --git a/syscall b/syscall index 3c765737a5e9146ffb241c67050c1be9bf28aab7..414b8e0be011c70d5c55692f4dd835184f33579f 160000 --- a/syscall +++ b/syscall @@ -1 +1 @@ -Subproject commit 3c765737a5e9146ffb241c67050c1be9bf28aab7 +Subproject commit 414b8e0be011c70d5c55692f4dd835184f33579f