Introduce syscall6. Add unlinkat and remove unlink and rmdir.
This commit is contained in:
committed by
Jeremy Soller
parent
2d346f1d61
commit
1cf631ce3f
+1
-1
@@ -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
@@ -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
@@ -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)]
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user