From 7a1409a910c4dd64d93d1470dc68fda464095ae5 Mon Sep 17 00:00:00 2001 From: Ibuki Omatsu Date: Wed, 27 May 2026 13:26:37 +0000 Subject: [PATCH] feat: Add multiple fds variant for call and std_fs_call --- Cargo.toml | 2 +- src/call.rs | 112 +++++++++++++++++++++++++++++++++++++----------- src/flag.rs | 7 ++- src/schemev2.rs | 4 ++ 4 files changed, 96 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 93fc08b1d5..37f97ce5da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "redox_syscall" -version = "0.7.5" +version = "0.8.0" 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 b7a421ad14..b7ededcc7d 100644 --- a/src/call.rs +++ b/src/call.rs @@ -125,7 +125,7 @@ pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result { SYS_FUTIMENS, fd, times.as_ptr() as usize, - times.len() * mem::size_of::(), + mem::size_of_val(times), ) } } @@ -302,49 +302,109 @@ pub fn sendfd(receiver_socket: usize, fd: usize, flags: usize, arg: u64) -> Resu } } +pub trait Call { + unsafe fn raw_call( + &self, + payload_ptr: *const u8, + len: usize, + flags: CallFlags, + metadata: &[u64], + ) -> Result; +} + +impl Call for usize { + unsafe fn raw_call( + &self, + payload_ptr: *const u8, + len: usize, + flags: CallFlags, + metadata: &[u64], + ) -> Result { + unsafe { + syscall5( + SYS_CALL, + *self, + payload_ptr as usize, + len, + metadata.len() | flags.bits(), + metadata.as_ptr() as usize, + ) + } + } +} + +impl Call for &[usize] { + unsafe fn raw_call( + &self, + payload_ptr: *const u8, + len: usize, + flags: CallFlags, + metadata: &[u64], + ) -> Result { + let combined_flags = flags | CallFlags::MULTIPLE_FDS; + unsafe { + syscall6( + SYS_CALL, + self.as_ptr() as usize, + payload_ptr as usize, + len, + metadata.len() | combined_flags.bits(), + metadata.as_ptr() as usize, + self.len() * mem::size_of::(), + ) + } + } +} + /// SYS_CALL interface, read-only variant -pub fn call_ro(fd: usize, payload: &mut [u8], flags: CallFlags, metadata: &[u64]) -> Result { - let combined_flags = flags | CallFlags::READ; +pub fn call_ro( + fd: T, + payload: &mut [u8], + flags: CallFlags, + metadata: &[u64], +) -> Result { unsafe { - syscall5( - SYS_CALL, - fd, - payload.as_mut_ptr() as usize, + fd.raw_call( + payload.as_mut_ptr(), payload.len(), - metadata.len() | combined_flags.bits(), - metadata.as_ptr() as usize, + flags | CallFlags::READ, + metadata, ) } } /// SYS_CALL interface, write-only variant -pub fn call_wo(fd: usize, payload: &[u8], flags: CallFlags, metadata: &[u64]) -> Result { - let combined_flags = flags | CallFlags::WRITE; +pub fn call_wo( + fd: T, + payload: &[u8], + flags: CallFlags, + metadata: &[u64], +) -> Result { unsafe { - syscall5( - SYS_CALL, - fd, - payload.as_ptr() as *mut u8 as usize, + fd.raw_call( + payload.as_ptr(), payload.len(), - metadata.len() | combined_flags.bits(), - metadata.as_ptr() as usize, + flags | CallFlags::WRITE, + metadata, ) } } /// SYS_CALL interface, read-write variant -pub fn call_rw(fd: usize, payload: &mut [u8], flags: CallFlags, metadata: &[u64]) -> Result { - let combined_flags = flags | CallFlags::READ | CallFlags::WRITE; +pub fn call_rw( + fd: T, + payload: &mut [u8], + flags: CallFlags, + metadata: &[u64], +) -> Result { unsafe { - syscall5( - SYS_CALL, - fd, - payload.as_mut_ptr() as usize, + fd.raw_call( + payload.as_mut_ptr(), payload.len(), - metadata.len() | combined_flags.bits(), - metadata.as_ptr() as usize, + flags | CallFlags::READ | CallFlags::WRITE, + metadata, ) } } -pub fn std_fs_call(fd: usize, payload: &mut [u8], metadata: &StdFsCallMeta) -> Result { +pub fn std_fs_call(fd: T, payload: &mut [u8], metadata: &StdFsCallMeta) -> Result { call_rw(fd, payload, CallFlags::STD_FS, metadata) } diff --git a/src/flag.rs b/src/flag.rs index 4cc55a95e5..458ef23d74 100644 --- a/src/flag.rs +++ b/src/flag.rs @@ -405,6 +405,9 @@ bitflags! { /// Call is a standard fs call, with metadata defined in `StdFsCallMeta` const STD_FS = 1 << 16; + + /// Call is taking multiple fds as an argument + const MULTIPLE_FDS = 1 << 17; } } @@ -422,7 +425,7 @@ pub enum StdFsCallKind { Futimens = 8, // 9 reserved in fscall RFC // Unlinkat = 10, - Realpathat = 11, + Relpathat = 11, Lock = 12, Unlock = 13, GetLock = 14, @@ -444,7 +447,7 @@ impl StdFsCallKind { 8 => Futimens, // 9 reserved in fscall RFC // 10 => Unlinkat, - 11 => Realpathat, + 11 => Relpathat, 12 => Lock, 13 => Unlock, 14 => GetLock, diff --git a/src/schemev2.rs b/src/schemev2.rs index 4c6056ee8d..f87f40d3b9 100644 --- a/src/schemev2.rs +++ b/src/schemev2.rs @@ -46,6 +46,10 @@ bitflags! { // If zero, the message is bidirectional, and the scheme is expected to pass the Ksmsg's // tag field to the Skmsg. Some opcodes require this flag to be set. const ONEWAY = 1; + + // If this flag is set, index 0 of Sqe's args stores the IDs buffer address, + // and index 1 stores the IDs buffer length. + const MULTIPLE_IDS = 1 << 1; } }