Introduce syscall6. Add unlinkat and remove unlink and rmdir.

This commit is contained in:
Ibuki Omatsu
2025-12-16 14:07:01 +00:00
committed by Jeremy Soller
parent 2d346f1d61
commit 1cf631ce3f
9 changed files with 128 additions and 23 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "redox_syscall"
version = "0.5.18"
version = "0.6.0"
description = "A Rust library to access raw Redox system calls"
license = "MIT"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
+6 -2
View File
@@ -12,9 +12,9 @@ pub const KERNEL_METADATA_SIZE: usize = 4 * PAGE_SIZE;
#[cfg(feature = "userspace")]
macro_rules! syscall {
($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, )?)?)?)?)?);)+) => {
($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, $($g:ident, )?)?)?)?)?)?);)+) => {
$(
pub unsafe fn $name($a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize)?)?)?)?)?) -> Result<usize> {
pub unsafe fn $name($a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize, $($g: usize)?)?)?)?)?)?) -> Result<usize> {
let ret: usize;
core::arch::asm!(
@@ -30,6 +30,9 @@ macro_rules! syscall {
in("x3") $e,
$(
in("x4") $f,
$(
in("x5") $g,
)?
)?
)?
)?
@@ -53,6 +56,7 @@ syscall! {
syscall3(a, b, c, d,);
syscall4(a, b, c, d, e,);
syscall5(a, b, c, d, e, f,);
syscall6(a, b, c, d, e, f, g,);
}
#[derive(Copy, Clone, Debug, Default)]
+6 -2
View File
@@ -12,9 +12,9 @@ pub const KERNEL_METADATA_SIZE: usize = 4 * PAGE_SIZE;
#[cfg(feature = "userspace")]
macro_rules! syscall {
($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, )?)?)?)?)?);)+) => {
($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, $($g:ident, )?)?)?)?)?)?);)+) => {
$(
pub unsafe fn $name($a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize)?)?)?)?)?) -> Result<usize> {
pub unsafe fn $name($a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize, $($g: usize)?)?)?)?)?)?) -> Result<usize> {
let ret: usize;
asm!(
@@ -30,6 +30,9 @@ macro_rules! syscall {
in("a3") $e,
$(
in("a4") $f,
$(
in("a5") $g,
)?
)?
)?
)?
@@ -53,6 +56,7 @@ syscall! {
syscall3(a, b, c, d,);
syscall4(a, b, c, d, e,);
syscall5(a, b, c, d, e, f,);
syscall6(a, b, c, d, e, f, g,);
}
#[derive(Copy, Clone, Debug, Default)]
+43
View File
@@ -52,6 +52,7 @@ syscall! {
// Must be done custom because LLVM reserves ESI
//syscall4(a, b, c, d, e,);
//syscall5(a, b, c, d, e, f,);
//syscall6(a, b, c, d, e, f, g,);
}
#[cfg(feature = "userspace")]
@@ -96,6 +97,48 @@ pub unsafe fn syscall5(
Error::demux(a)
}
#[cfg(feature = "userspace")]
pub unsafe fn syscall6(
mut a: usize,
b: usize,
c: usize,
d: usize,
e: usize,
f: usize,
g: usize,
) -> Result<usize> {
#[repr(C)]
struct PackedArgs {
arg4: usize,
arg6: usize,
nr: usize,
}
let args = PackedArgs {
arg4: e,
arg6: g,
nr: a,
};
let args_ptr = &args as *const PackedArgs;
asm!(
"push ebp",
"push esi",
"mov esi, [eax + 0]", // arg4 -> esi
"mov ebp, [eax + 4]", // arg6 -> ebp
"mov eax, [eax + 8]", // nr -> eax
"int 0x80",
"pop esi",
"pop ebp",
inout("eax") args_ptr => a,
in("ebx") b,
in("ecx") c,
in("edx") d,
in("edi") f,
options(nostack),
);
Error::demux(a)
}
#[derive(Copy, Clone, Debug, Default)]
#[repr(C)]
pub struct IntRegisters {
+6 -2
View File
@@ -10,9 +10,9 @@ pub const KERNEL_METADATA_SIZE: usize = 4 * PAGE_SIZE;
#[cfg(feature = "userspace")]
macro_rules! syscall {
($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, )?)?)?)?)?);)+) => {
($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, $($g:ident, )?)?)?)?)?)?);)+) => {
$(
pub unsafe fn $name(mut $a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize)?)?)?)?)?) -> crate::error::Result<usize> {
pub unsafe fn $name(mut $a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize, $($g: usize)?)?)?)?)?)?) -> crate::error::Result<usize> {
core::arch::asm!(
"syscall",
inout("rax") $a,
@@ -26,6 +26,9 @@ macro_rules! syscall {
in("r10") $e,
$(
in("r8") $f,
$(
in("r9") $g,
)?
)?
)?
)?
@@ -50,6 +53,7 @@ syscall! {
syscall3(a, b, c, d,);
syscall4(a, b, c, d, e,);
syscall5(a, b, c, d, e, f,);
syscall6(a, b, c, d, e, f, g,);
}
#[derive(Copy, Clone, Debug, Default)]
+55 -12
View File
@@ -199,24 +199,67 @@ pub fn openat<T: AsRef<str>>(
)
}
}
/// Open a file at a specific path with filter
pub fn openat_with_filter<T: AsRef<str>>(
fd: usize,
path: T,
flags: usize,
fcntl_flags: usize,
euid: u32,
egid: u32,
) -> Result<usize> {
let path = path.as_ref();
unsafe {
syscall6(
SYS_OPENAT_WITH_FILTER,
fd,
path.as_ptr() as usize,
path.len(),
flags | fcntl_flags,
// NOTE: Short-term solution to allow namespace management.
// In the long term, we need to figure out how we should best handle
// Unix permissions using capabilities.
euid as usize,
egid as usize,
)
}
}
/// Remove a file at at specific path
pub fn unlinkat<T: AsRef<str>>(fd: usize, path: T, flags: usize) -> Result<usize> {
let path = path.as_ref();
unsafe { syscall4(SYS_UNLINKAT, fd, path.as_ptr() as usize, path.len(), flags) }
}
/// Remove a file at at specific path with filter
pub fn unlinkat_with_filter<T: AsRef<str>>(
fd: usize,
path: T,
flags: usize,
euid: u32,
egid: u32,
) -> Result<usize> {
let path = path.as_ref();
unsafe {
syscall6(
SYS_UNLINKAT_WITH_FILTER,
fd,
path.as_ptr() as usize,
path.len(),
flags,
// NOTE: Short-term solution to allow namespace management.
// In the long term, we need to figure out how we should best handle
// Unix permissions using capabilities.
euid as usize,
egid as usize,
)
}
}
/// Read from a file descriptor into a buffer
pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> {
unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) }
}
/// Remove a directory
pub fn rmdir<T: AsRef<str>>(path: T) -> Result<usize> {
let path = path.as_ref();
unsafe { syscall2(SYS_RMDIR, path.as_ptr() as usize, path.len()) }
}
/// Remove a file
pub fn unlink<T: AsRef<str>>(path: T) -> Result<usize> {
let path = path.as_ref();
unsafe { syscall2(SYS_UNLINK, path.as_ptr() as usize, path.len()) }
}
/// Write a buffer to a file descriptor
///
/// The kernel will attempt to write the bytes in `buf` to the file descriptor `fd`, returning
+4
View File
@@ -204,6 +204,10 @@ pub const O_STAT: usize = 0x2000_0000;
pub const O_SYMLINK: usize = 0x4000_0000;
pub const O_NOFOLLOW: usize = 0x8000_0000;
pub const O_ACCMODE: usize = O_RDONLY | O_WRONLY | O_RDWR;
pub const O_FCNTL_MASK: usize = O_NONBLOCK | O_APPEND | O_ASYNC | O_FSYNC;
/// Remove directory instead of unlinking file.
pub const AT_REMOVEDIR: usize = 0x200;
// The top 48 bits of PTRACE_* are reserved, for now
+3 -2
View File
@@ -12,8 +12,9 @@ pub const SYS_RET_FILE: usize = 0x0010_0000;
pub const SYS_OPEN: usize = SYS_CLASS_PATH | SYS_RET_FILE | 5;
pub const SYS_OPENAT: usize = SYS_CLASS_PATH | SYS_RET_FILE | 7;
pub const SYS_RMDIR: usize = SYS_CLASS_PATH | 84;
pub const SYS_UNLINK: usize = SYS_CLASS_PATH | 10;
pub const SYS_OPENAT_WITH_FILTER: usize = SYS_CLASS_PATH | SYS_RET_FILE | 985;
pub const SYS_UNLINKAT: usize = SYS_CLASS_PATH | 263;
pub const SYS_UNLINKAT_WITH_FILTER: usize = SYS_CLASS_PATH | 986;
pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6;
pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41;
+4 -2
View File
@@ -134,8 +134,9 @@ pub enum Opcode {
OpenAt = 29, // fd, buf_ptr, buf_len, flags
Flink = 30,
Recvfd = 31,
UnlinkAt = 32, // fd, path_ptr, path_len (utf8), flags
}
impl Opcode {
@@ -178,9 +179,10 @@ impl Opcode {
29 => OpenAt,
30 => Flink,
31 => Recvfd,
32 => UnlinkAt,
_ => return None,
})
}