From 52b1d04e1212e1c0683d08c164a1f814e812705f Mon Sep 17 00:00:00 2001 From: Ibuki Omatsu Date: Fri, 29 May 2026 11:13:35 +0000 Subject: [PATCH] feat: Implement realpathat for ramfs --- Cargo.lock | 116 ++++++++++++++++++------------------ Cargo.toml | 8 +-- bootstrap/Cargo.lock | 16 ++--- bootstrap/Cargo.toml | 6 +- bootstrap/src/procmgr.rs | 36 ++++++------ ramfs/src/scheme.rs | 123 +++++++++++++++++++++++++++------------ 6 files changed, 176 insertions(+), 129 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a5c67485a..465cec1c0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,7 +13,7 @@ dependencies = [ "pcid", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", "spin", ] @@ -48,7 +48,7 @@ dependencies = [ "plain", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "ron", "rustc-hash", "scheme-utils", @@ -80,7 +80,7 @@ dependencies = [ "log", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -193,7 +193,7 @@ dependencies = [ "libc", "libredox", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", ] @@ -225,7 +225,7 @@ dependencies = [ "fdt 0.2.0-alpha1", "libredox", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -423,7 +423,7 @@ dependencies = [ "libredox", "log", "redox-log", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -514,7 +514,7 @@ dependencies = [ "libc", "libredox", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -582,7 +582,7 @@ dependencies = [ "log", "partitionlib", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", ] @@ -599,7 +599,7 @@ dependencies = [ "log", "redox-ioctl", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", ] @@ -610,7 +610,7 @@ dependencies = [ "daemon", "libredox", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", ] @@ -667,7 +667,7 @@ dependencies = [ "log", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -747,7 +747,7 @@ dependencies = [ "ransid", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", ] @@ -768,7 +768,7 @@ dependencies = [ "ransid", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", "serde", "toml", @@ -1061,7 +1061,7 @@ dependencies = [ "log", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -1076,7 +1076,7 @@ dependencies = [ "pcid", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", "spin", ] @@ -1100,7 +1100,7 @@ dependencies = [ "range-alloc", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "void", ] @@ -1124,7 +1124,7 @@ dependencies = [ "libc", "libredox", "plain", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "serde", "serde_json", "toml", @@ -1141,7 +1141,7 @@ dependencies = [ "log", "orbclient", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", ] @@ -1166,7 +1166,7 @@ dependencies = [ "rand 0.10.1", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", ] @@ -1193,7 +1193,7 @@ dependencies = [ "libredox", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -1228,15 +1228,15 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ "bitflags 2.11.1", "ioslice", "libc", "plain", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -1260,7 +1260,7 @@ dependencies = [ "driver-block", "libredox", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -1285,7 +1285,7 @@ dependencies = [ "daemon", "libredox", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", ] @@ -1342,7 +1342,7 @@ dependencies = [ "redox-log", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", "smoltcp", ] @@ -1398,7 +1398,7 @@ dependencies = [ "partitionlib", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "smallvec 1.15.1", ] @@ -1525,7 +1525,7 @@ dependencies = [ "pico-args", "plain", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", "serde", ] @@ -1541,7 +1541,7 @@ dependencies = [ "log", "pcid", "pico-args", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "serde", "toml", ] @@ -1627,7 +1627,7 @@ dependencies = [ "orbclient", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -1649,7 +1649,7 @@ dependencies = [ "libredox", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "redox_termios", "scheme-utils", ] @@ -1683,7 +1683,7 @@ dependencies = [ "indexmap", "libredox", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", "slab", ] @@ -1789,7 +1789,7 @@ dependencies = [ "rand_core 0.5.1", "raw-cpuid", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", "sha2", ] @@ -1851,10 +1851,10 @@ dependencies = [ [[package]] name = "redox-ioctl" version = "0.1.0" -source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#546bc6fb21b990ca9195a1115717c9a842fe4909" +source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#0813a23294ba082037cf09d0afd2643e9e77b4ba" dependencies = [ "drm-sys", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -1870,19 +1870,19 @@ dependencies = [ [[package]] name = "redox-scheme" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e58cb7dee1058575f320f9bfa32c7c0eda857e285c2a163a0eb595d37add09cd" +checksum = "ecd26e368655cb4fdda914512c46c5640221ebe5fa6df5da19c941b9f06ed153" dependencies = [ "libredox", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] name = "redox_event" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea3e412d205440c7b0218af26247226f979ed1201674cda7a33cc70609084b5" +checksum = "8c07d0d6d291e3a951bd847b1cd4af32fc6243d64116cf7702838c02797688b7" dependencies = [ "bitflags 2.11.1", "libredox", @@ -1899,9 +1899,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" +checksum = "7c7591fa2c6b601dfcfe5f043f65a1c39fcdf50efefcd7f1572e538c1f4b398d" dependencies = [ "bitflags 2.11.1", ] @@ -1921,7 +1921,7 @@ dependencies = [ "libredox", "qemu-exit", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "redox_termios", ] @@ -1997,7 +1997,7 @@ dependencies = [ "log", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -2012,7 +2012,7 @@ dependencies = [ "log", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -2051,7 +2051,7 @@ dependencies = [ "log", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", "spin", ] @@ -2062,7 +2062,7 @@ version = "0.0.0" dependencies = [ "libredox", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -2452,7 +2452,7 @@ dependencies = [ "log", "orbclient", "plain", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "rehid", "smallvec 1.15.1", "xhcid", @@ -2464,7 +2464,7 @@ version = "0.1.0" dependencies = [ "common", "log", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "xhcid", ] @@ -2478,7 +2478,7 @@ dependencies = [ "libredox", "plain", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "thiserror 2.0.18", "xhcid", ] @@ -2516,7 +2516,7 @@ dependencies = [ "orbclient", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -2543,7 +2543,7 @@ dependencies = [ "orbclient", "ransid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -2559,7 +2559,7 @@ dependencies = [ "log", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "spin", "static_assertions", "thiserror 2.0.18", @@ -2578,7 +2578,7 @@ dependencies = [ "log", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "static_assertions", "thiserror 2.0.18", ] @@ -2598,7 +2598,7 @@ dependencies = [ "orbclient", "pcid", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "spin", "static_assertions", "virtio-core", @@ -2615,7 +2615,7 @@ dependencies = [ "libredox", "log", "pcid", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "static_assertions", "virtio-core", ] @@ -2955,7 +2955,7 @@ dependencies = [ "plain", "redox-scheme", "redox_event", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "regex", "scheme-utils", "serde", @@ -2992,7 +2992,7 @@ dependencies = [ "daemon", "libredox", "redox-scheme", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", "scheme-utils", ] diff --git a/Cargo.toml b/Cargo.toml index 396d7da9c4..747d3eb4d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,19 +85,19 @@ edid = "0.3.0" #TODO: edid is abandoned, fork it and maintain? fdt = "0.1.5" libc = "0.2.181" log = "0.4" -libredox = "0.1.16" +libredox = "0.1.17" orbclient = "0.3.51" psf-rs = "2.2.0" parking_lot = "0.12" pico-args = "0.5" plain = "0.2.3" ransid = "0.4" -redox_event = "0.4.6" +redox_event = "0.4.7" redox-ioctl = { git = "https://gitlab.redox-os.org/redox-os/relibc.git" } redox-log = { git = "https://gitlab.redox-os.org/redox-os/redox-log.git" } redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false } -redox-scheme = "0.11.0" -redox_syscall = { version = "0.7.5", features = ["std"] } +redox-scheme = "0.11.1" +redox_syscall = { version = "0.8.0", features = ["std"] } redox_termios = "0.1.3" ron = "0.8.1" serde = { version = "1", features = ["derive"] } diff --git a/bootstrap/Cargo.lock b/bootstrap/Cargo.lock index 2cc30762a4..83254f4d6b 100644 --- a/bootstrap/Cargo.lock +++ b/bootstrap/Cargo.lock @@ -41,7 +41,7 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "generic-rt" version = "0.1.0" -source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#2b69838a481b7be9826b41e06a0b8f1346b80f9e" +source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#0813a23294ba082037cf09d0afd2643e9e77b4ba" [[package]] name = "goblin" @@ -77,9 +77,9 @@ checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ "bitflags", "libc", @@ -151,7 +151,7 @@ checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717" [[package]] name = "redox-rt" version = "0.1.0" -source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#2b69838a481b7be9826b41e06a0b8f1346b80f9e" +source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#0813a23294ba082037cf09d0afd2643e9e77b4ba" dependencies = [ "bitflags", "generic-rt", @@ -165,9 +165,9 @@ dependencies = [ [[package]] name = "redox-scheme" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e58cb7dee1058575f320f9bfa32c7c0eda857e285c2a163a0eb595d37add09cd" +checksum = "ecd26e368655cb4fdda914512c46c5640221ebe5fa6df5da19c941b9f06ed153" dependencies = [ "libredox", "redox_syscall", @@ -175,9 +175,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" +checksum = "7c7591fa2c6b601dfcfe5f043f65a1c39fcdf50efefcd7f1572e538c1f4b398d" dependencies = [ "bitflags", ] diff --git a/bootstrap/Cargo.toml b/bootstrap/Cargo.toml index 82120c213d..9f8954e99f 100644 --- a/bootstrap/Cargo.toml +++ b/bootstrap/Cargo.toml @@ -12,12 +12,12 @@ hashbrown = { version = "0.15", default-features = false, features = [ "default-hasher", ] } linked_list_allocator = "0.10" -libredox = { version = "0.1.16", default-features = false, features = ["protocol"] } +libredox = { version = "0.1.17", default-features = false, features = ["protocol"] } log = { version = "0.4", default-features = false } plain = "0.2" redox-initfs = { path = "../initfs", default-features = false } -redox_syscall = "0.7.4" -redox-scheme = { version = "0.11.0", default-features = false } +redox_syscall = "0.8.0" +redox-scheme = { version = "0.11.1", default-features = false } redox-path = "0.3.1" slab = { version = "0.4.9", default-features = false } arrayvec = { version = "0.7.6", default-features = false } diff --git a/bootstrap/src/procmgr.rs b/bootstrap/src/procmgr.rs index ce37d574c9..8a68edbde5 100644 --- a/bootstrap/src/procmgr.rs +++ b/bootstrap/src/procmgr.rs @@ -725,10 +725,7 @@ impl<'a> ProcScheme<'a> { sig_pctl: None, // TODO rtqs: Vec::new(), })); - if let Err(err) = new_process - .borrow_mut() - .sync_kernel_attrs(&self.auth) - { + if let Err(err) = new_process.borrow_mut().sync_kernel_attrs(&self.auth) { log::warn!("Failed to set kernel attrs when forking: {err}"); } @@ -919,7 +916,7 @@ impl<'a> ProcScheme<'a> { mut op: OpCall, awoken: &mut VecDeque, ) -> Poll { - let id = op.fd; + let id = op.fd(); let (payload, metadata) = op.payload_and_metadata(); match self.handles[id] { Handle::Init => Response::ready_err(EBADF, op), @@ -1068,25 +1065,27 @@ impl<'a> ProcScheme<'a> { // FIXME remove this ProcCall variant ProcCall::Setrens => Response::ready_err(EINVAL, op), ProcCall::SetProcPriority => { - let target_pid = NonZeroUsize::new(metadata[1] as usize).map_or(fd_pid, |n| ProcessId(n.get())); + let target_pid = NonZeroUsize::new(metadata[1] as usize) + .map_or(fd_pid, |n| ProcessId(n.get())); let new_prio = metadata[2] as u32; Ready(Response::new( - self.on_setprocprio(fd_pid, target_pid, new_prio).map(|()| 0), - op + self.on_setprocprio(fd_pid, target_pid, new_prio) + .map(|()| 0), + op, )) - }, + } ProcCall::GetProcPriority => { let target_pid = NonZeroUsize::new(metadata[1] as usize) .map_or(fd_pid, |n| ProcessId(n.get())); Ready(Response::new( - self.on_getprocprio(fd_pid, target_pid).map(|prio| prio as usize), + self.on_getprocprio(fd_pid, target_pid) + .map(|prio| prio as usize), op, )) - }, - + } } } Handle::Ps(_) => Response::ready_err(EOPNOTSUPP, op), @@ -2566,7 +2565,12 @@ impl<'a> ProcScheme<'a> { return Err(Error::new(EINVAL)); } - let caller_euid = self.processes.get(&caller_pid).ok_or(Error::new(ESRCH))?.borrow().euid; + let caller_euid = self + .processes + .get(&caller_pid) + .ok_or(Error::new(ESRCH))? + .borrow() + .euid; let target_rc = self.processes.get(&target_pid).ok_or(Error::new(ESRCH))?; let mut target = target_rc.borrow_mut(); @@ -2583,11 +2587,7 @@ impl<'a> ProcScheme<'a> { Ok(()) } - fn on_getprocprio( - &self, - caller_pid: ProcessId, - target_pid: ProcessId, - ) -> Result { + fn on_getprocprio(&self, caller_pid: ProcessId, target_pid: ProcessId) -> Result { let target_rc = self.processes.get(&target_pid).ok_or(Error::new(ESRCH))?; Ok(target_rc.borrow().prio) } diff --git a/ramfs/src/scheme.rs b/ramfs/src/scheme.rs index 421d814126..79e7604458 100644 --- a/ramfs/src/scheme.rs +++ b/ramfs/src/scheme.rs @@ -6,7 +6,7 @@ use scheme_utils::{FpathWriter, HandleMap}; use syscall::dirent::{DirEntry, DirentBuf, DirentKind}; use syscall::error::{ EACCES, EBADF, EBADFD, EEXIST, EINVAL, EIO, EISDIR, ENOMEM, ENOSYS, ENOTDIR, ENOTEMPTY, - EOPNOTSUPP, EOVERFLOW, EPERM, + EOPNOTSUPP, EOVERFLOW, EPERM, ERANGE, }; use syscall::flag::{ StdFsCallKind, O_ACCMODE, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_STAT, O_TRUNC, @@ -25,7 +25,14 @@ use crate::filesystem::{self, File, FileData, Filesystem, Inode}; enum Handle { Inode(usize), - SchemeRoot, +} + +impl Handle { + fn as_inode(&self) -> Result { + match self { + &Self::Inode(inode) => Ok(inode), + } + } } pub struct Scheme { @@ -164,7 +171,7 @@ impl Scheme { impl SchemeSync for Scheme { fn scheme_root(&mut self) -> Result { - Ok(self.handles.insert(Handle::SchemeRoot)) + Ok(self.handles.insert(Handle::Inode(Filesystem::ROOT_INODE))) } fn openat( &mut self, @@ -174,7 +181,7 @@ impl SchemeSync for Scheme { fcntl_flags: u32, ctx: &CallerCtx, ) -> Result { - if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) { + if self.handles.get(dirfd)?.as_inode()? != Filesystem::ROOT_INODE { return Err(Error::new(EACCES)); } @@ -272,7 +279,7 @@ impl SchemeSync for Scheme { } fn unlinkat(&mut self, dirfd: usize, path: &str, flags: usize, ctx: &CallerCtx) -> Result<()> { { - if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) { + if !self.handles.get(dirfd)?.as_inode()? != Filesystem::ROOT_INODE { return Err(Error::new(EACCES)); } } @@ -294,10 +301,7 @@ impl SchemeSync for Scheme { let Ok(offset) = usize::try_from(offset) else { return Ok(0); }; - let inode = match self.handles.get(fd)? { - Handle::Inode(inode) => inode, - Handle::SchemeRoot => return Err(Error::new(EISDIR)), - }; + let inode = self.handles.get(fd)?.as_inode()?; let file = self .filesystem .files @@ -330,10 +334,7 @@ impl SchemeSync for Scheme { let Ok(offset) = usize::try_from(opaque_offset) else { return Ok(buf); }; - let inode = match self.handles.get(fd)? { - Handle::Inode(inode) => inode, - Handle::SchemeRoot => return Err(Error::new(EISDIR)), - }; + let inode = self.handles.get(fd)?.as_inode()?; let file = self .filesystem .files @@ -365,10 +366,7 @@ impl SchemeSync for Scheme { let Ok(offset) = usize::try_from(offset) else { return Ok(0); }; - let inode = match self.handles.get(fd)? { - Handle::Inode(inode) => inode, - Handle::SchemeRoot => return Err(Error::new(EISDIR)), - }; + let inode = self.handles.get(fd)?.as_inode()?; let file = self .filesystem .files @@ -395,10 +393,7 @@ impl SchemeSync for Scheme { } } fn fchmod(&mut self, fd: usize, mode: u16, _ctx: &CallerCtx) -> Result<()> { - let inode = match self.handles.get(fd)? { - Handle::Inode(inode) => inode, - Handle::SchemeRoot => return Err(Error::new(EISDIR)), - }; + let inode = self.handles.get(fd)?.as_inode()?; let file = self .filesystem .files @@ -460,11 +455,7 @@ impl SchemeSync for Scheme { } fn fpath(&mut self, fd: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result { FpathWriter::with(buf, &self.scheme_name, |w| { - let mut current_inode = match *self.handles.get(fd)? { - Handle::Inode(inode) => inode, - Handle::SchemeRoot => return Err(Error::new(EISDIR)), - }; - + let mut current_inode = self.handles.get(fd)?.as_inode()?; let mut chain = Vec::new(); let mut current_info = self @@ -508,10 +499,7 @@ impl SchemeSync for Scheme { Err(Error::new(ENOSYS)) } fn fstat(&mut self, fd: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> { - let inode = match *self.handles.get(fd)? { - Handle::Inode(inode) => inode, - Handle::SchemeRoot => return Err(Error::new(EISDIR)), - }; + let inode = self.handles.get(fd)?.as_inode()?; let block_size = self.filesystem.block_size(); let file = self @@ -586,10 +574,7 @@ impl SchemeSync for Scheme { Ok(()) } fn ftruncate(&mut self, fd: usize, size: u64, _ctx: &CallerCtx) -> Result<()> { - let inode = match self.handles.get(fd)? { - Handle::Inode(inode) => inode, - Handle::SchemeRoot => return Err(Error::new(EISDIR)), - }; + let inode = self.handles.get(fd)?.as_inode()?; let file = self .filesystem .files @@ -615,10 +600,7 @@ impl SchemeSync for Scheme { Ok(()) } fn futimens(&mut self, fd: usize, times: &[TimeSpec], _ctx: &CallerCtx) -> Result<()> { - let inode = match self.handles.get(fd)? { - Handle::Inode(inode) => inode, - Handle::SchemeRoot => return Err(Error::new(EISDIR)), - }; + let inode = self.handles.get(fd)?.as_inode()?; let file = self .filesystem .files @@ -634,6 +616,71 @@ impl SchemeSync for Scheme { Ok(()) } + fn relpathat( + &mut self, + dir_id: usize, + id: usize, + path: &mut [u8], + _ctx: &CallerCtx, + ) -> Result { + let (&Handle::Inode(dir_inode), &Handle::Inode(mut current_inode)) = + (self.handles.get(dir_id)?, self.handles.get(id)?) + else { + return Err(Error::new(EBADF)); + }; + + let mut chain = Vec::new(); + + let mut current_info = self + .filesystem + .files + .get(¤t_inode) + .ok_or(Error::new(EBADFD))?; + + while current_inode != dir_inode && current_inode != Filesystem::ROOT_INODE { + let parent_info = self + .filesystem + .files + .get(¤t_info.parent.0) + .ok_or(Error::new(EBADFD))?; + + let FileData::Directory(ref dir) = parent_info.data else { + return Err(Error::new(EBADFD)); + }; + + let (name, _) = dir + .iter() + .find(|(_name, inode)| inode.0 == current_inode) + .ok_or(Error::new(ENOENT))?; + + chain.push(name); + + current_inode = current_info.parent.0; + current_info = parent_info; + } + + let mut offset = 0; + for (i, component) in chain.iter().rev().enumerate() { + if i != 0 { + if offset >= path.len() { + return Err(Error::new(ERANGE)); + } + path[offset] = b'/'; + offset += 1; + } + + let bytes: &[u8] = component.as_ref(); + if offset + bytes.len() > path.len() { + return Err(Error::new(ERANGE)); + } + + path[offset..offset + bytes.len()].copy_from_slice(bytes); + offset += bytes.len(); + } + + Ok(offset) + } + fn std_fs_call( &mut self, id: usize,