From 95f4fed4e273b50618f81cdffb23088cada87e0e Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 19 Jan 2026 12:39:59 -0700 Subject: [PATCH] Implement fscall RFC --- Cargo.toml | 2 +- src/call.rs | 6 +++++- src/data.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/flag.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/schemev2.rs | 2 ++ 5 files changed, 97 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a761213f2c..ff68b189a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "redox_syscall" -version = "0.7.0" +version = "0.7.1" description = "A Rust library to access raw Redox system calls" license = "MIT" authors = ["Jeremy Soller "] diff --git a/src/call.rs b/src/call.rs index 3fbc98673c..b7a421ad14 100644 --- a/src/call.rs +++ b/src/call.rs @@ -1,6 +1,6 @@ use super::{ arch::*, - data::{Map, Stat, StatVfs, TimeSpec}, + data::{Map, Stat, StatVfs, StdFsCallMeta, TimeSpec}, error::Result, flag::*, number::*, @@ -344,3 +344,7 @@ pub fn call_rw(fd: usize, payload: &mut [u8], flags: CallFlags, metadata: &[u64] ) } } + +pub fn std_fs_call(fd: usize, payload: &mut [u8], metadata: &StdFsCallMeta) -> Result { + call_rw(fd, payload, CallFlags::STD_FS, metadata) +} diff --git a/src/data.rs b/src/data.rs index 746f87ef4b..cfa9bee2c9 100644 --- a/src/data.rs +++ b/src/data.rs @@ -4,7 +4,7 @@ use core::{ slice, }; -use crate::flag::{EventFlags, MapFlags, PtraceFlags}; +use crate::flag::{EventFlags, MapFlags, PtraceFlags, StdFsCallKind}; #[derive(Copy, Clone, Debug, Default)] #[repr(C)] @@ -174,6 +174,49 @@ impl DerefMut for StatVfs { } } +#[derive(Copy, Clone, Debug, Default, PartialEq)] +#[repr(C, packed)] +pub struct StdFsCallMeta { + pub kind: u8, // enum StdFsCallKind + _rsvd: [u8; 7], + pub arg1: u64, + pub arg2: u64, +} + +impl StdFsCallMeta { + pub fn new(kind: StdFsCallKind, arg1: u64, arg2: u64) -> Self { + Self { + kind: kind as u8, + _rsvd: [0; 7], + arg1, + arg2, + } + } +} + +impl Deref for StdFsCallMeta { + type Target = [u64]; + fn deref(&self) -> &[u64] { + unsafe { + slice::from_raw_parts( + self as *const StdFsCallMeta as *const u64, + mem::size_of::() / mem::size_of::(), + ) + } + } +} + +impl DerefMut for StdFsCallMeta { + fn deref_mut(&mut self) -> &mut [u64] { + unsafe { + slice::from_raw_parts_mut( + self as *mut StdFsCallMeta as *mut u64, + mem::size_of::() / mem::size_of::(), + ) + } + } +} + #[derive(Copy, Clone, Debug, Default, PartialEq)] #[repr(C)] pub struct TimeSpec { diff --git a/src/flag.rs b/src/flag.rs index e0cc36d8e5..51f827a537 100644 --- a/src/flag.rs +++ b/src/flag.rs @@ -402,6 +402,51 @@ bitflags! { const FD_CLONE = 1 << 13; const FD_UPPER = 1 << 14; const FD_CLOEXEC = 1 << 15; + + /// Call is a standard fs call, with metadata defined in `StdFsCallMeta` + const STD_FS = 1 << 16; + } +} + +#[repr(u8)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum StdFsCallKind { + /*TODO: remove old syscalls + Fchmod = 1, + Fchown = 2, + Getdents = 3, + Fstat = 4, + Fstatvfs = 5, + Fsync = 6, + Ftruncate = 7, + Futimens = 8, + // 9 reserved in fscall RFC + Unlinkat = 10, + */ + Realpathat = 11, +} + +impl StdFsCallKind { + pub fn try_from_raw(raw: u8) -> Option { + use StdFsCallKind::*; + + // TODO: Use a library where this match can be automated. + Some(match raw { + /* + 1 => Fchmod, + 2 => Fchown, + 3 => Getdents, + 4 => Fstat, + 5 => Fstatvfs, + 6 => Fsync, + 7 => Ftruncate, + 8 => Futimens, + // 9 reserved in fscall RFC + 10 => Unlinkat, + */ + 11 => Realpathat, + _ => return None, + }) } } diff --git a/src/schemev2.rs b/src/schemev2.rs index 54dc9378db..38bcd8c5c6 100644 --- a/src/schemev2.rs +++ b/src/schemev2.rs @@ -145,6 +145,7 @@ pub enum Opcode { Recvfd = 31, UnlinkAt = 32, // fd, path_ptr, path_len (utf8), flags + StdFsCall = 33, } impl Opcode { @@ -187,6 +188,7 @@ impl Opcode { 31 => Recvfd, 32 => UnlinkAt, + 33 => StdFsCall, _ => return None, })