Improved scheme protocol with offset+flags as read/write args

This commit is contained in:
Jacob Lorentzon
2024-06-14 11:18:10 +00:00
committed by Jeremy Soller
parent 3e9d68c6b2
commit ef099bdd2e
6 changed files with 200 additions and 3 deletions
+1
View File
@@ -13,6 +13,7 @@ name = "syscall"
[features]
rustc-dep-of-std = ["core", "bitflags/rustc-dep-of-std"]
std = []
[dependencies]
bitflags = "2.4"
+9
View File
@@ -44,6 +44,15 @@ impl fmt::Display for Error {
f.write_str(self.text())
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
#[cfg(feature = "std")]
impl From<Error> for std::io::Error {
fn from(value: Error) -> Self {
std::io::Error::from_raw_os_error(value.errno)
}
}
pub const EPERM: i32 = 1; /* Operation not permitted */
pub const ENOENT: i32 = 2; /* No such file or directory */
+10
View File
@@ -72,6 +72,7 @@ pub const SKMSG_FOBTAINFD: usize = 2;
// TODO: Split SendFdFlags into caller flags and flags that the scheme receives?
bitflags::bitflags! {
#[derive(Clone, Copy, Debug)]
pub struct SendFdFlags: usize {
/// If set, the kernel will enforce that the file descriptor is exclusively owned.
///
@@ -82,6 +83,7 @@ bitflags::bitflags! {
}
}
bitflags::bitflags! {
#[derive(Clone, Copy, Debug)]
pub struct FobtainFdFlags: usize {
/// If set, `packet.c` specifies the destination file descriptor slot, otherwise the lowest
/// available slot will be selected, and placed in the usize pointed to by `packet.c`.
@@ -335,3 +337,11 @@ bitflags! {
// TODO: MAYMOVE, DONTUNMAP
}
}
bitflags! {
pub struct RwFlags: u32 {
const NONBLOCK = 1;
const APPEND = 2;
// TODO: sync/dsync
// TODO: O_DIRECT?
}
}
+5 -3
View File
@@ -1,4 +1,4 @@
#![cfg_attr(not(test), no_std)]
#![cfg_attr(not(any(feature = "std", test)), no_std)]
#[cfg(test)]
extern crate core;
@@ -10,7 +10,6 @@ pub use self::error::*;
pub use self::flag::*;
pub use self::io::*;
pub use self::number::*;
pub use self::scheme::*;
#[cfg(all(any(target_os = "none", target_os = "redox"), target_arch = "arm"))]
#[path="arch/nonredox.rs"]
@@ -54,8 +53,11 @@ pub mod io;
/// Call numbers used by each system call
pub mod number;
/// A trait useful for scheme handlers
/// V2 scheme format
pub mod schemev2;
pub mod scheme;
pub use scheme::*;
#[cfg(test)]
mod tests;
+2
View File
@@ -19,7 +19,9 @@ pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6;
pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41;
pub const SYS_DUP2: usize = SYS_CLASS_FILE | SYS_RET_FILE | 63;
pub const SYS_READ: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 3;
pub const SYS_READ2: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 35;
pub const SYS_WRITE: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 4;
pub const SYS_WRITE2: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 45;
pub const SYS_LSEEK: usize = SYS_CLASS_FILE | 19;
pub const SYS_FCHMOD: usize = SYS_CLASS_FILE | 94;
pub const SYS_FCHOWN: usize = SYS_CLASS_FILE | 207;
+173
View File
@@ -0,0 +1,173 @@
use core::ops::{Deref, DerefMut};
use core::{mem, slice};
use bitflags::bitflags;
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct Sqe {
pub opcode: u8,
pub sqe_flags: SqeFlags,
pub _rsvd: u16, // TODO: priority
pub tag: u32,
pub args: [u64; 6],
pub caller: u64,
}
impl Deref for Sqe {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self as *const Sqe as *const u8, mem::size_of::<Sqe>())
}
}
}
impl DerefMut for Sqe {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self as *mut Sqe as *mut u8, mem::size_of::<Sqe>())
}
}
}
bitflags! {
#[derive(Clone, Copy, Debug, Default)]
pub struct SqeFlags: u8 {
// 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;
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct Cqe {
pub flags: u8, // bits 3:0 are CqeOpcode
pub extra_raw: [u8; 3],
pub tag: u32,
pub result: u64,
}
impl Deref for Cqe {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self as *const Cqe as *const u8, mem::size_of::<Cqe>())
}
}
}
impl DerefMut for Cqe {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self as *mut Cqe as *mut u8, mem::size_of::<Cqe>())
}
}
}
bitflags! {
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct NewFdFlags: u8 {
const POSITIONED = 1;
}
}
impl Cqe {
pub fn extra(&self) -> u32 {
u32::from_ne_bytes([self.extra_raw[0], self.extra_raw[1], self.extra_raw[2], 0])
}
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CqeOpcode {
RespondRegular,
RespondWithFd,
SendFevent, // no tag
ObtainFd,
// TODO: ProvideMmap
}
impl CqeOpcode {
pub fn try_from_raw(raw: u8) -> Option<Self> {
Some(match raw {
0 => Self::RespondRegular,
1 => Self::RespondWithFd,
2 => Self::SendFevent,
3 => Self::ObtainFd,
_ => return None,
})
}
}
#[repr(u8)]
#[non_exhaustive]
#[derive(Clone, Copy, Debug)]
pub enum Opcode {
Open = 0, // path_ptr, path_len (utf8), flags
Rmdir = 1, // path_ptr, path_len (utf8)
Unlink = 2, // path_ptr, path_len (utf8)
Close = 3, // fd
Dup = 4, // old fd, buf_ptr, buf_len
Read = 5, // fd, buf_ptr, buf_len, TODO offset, TODO flags, _
Write = 6, // fd, buf_ptr, buf_len, TODO offset, TODO flags)
Fsize = 7, // fd
Fchmod = 8, // fd, new mode
Fchown = 9, // fd, new uid, new gid
Fcntl = 10, // fd, cmd, arg
Fevent = 11, // fd, requested mask
Sendfd = 12,
Fpath = 13, // fd, buf_ptr, buf_len
Frename = 14,
Fstat = 15, // fd, buf_ptr, buf_len
Fstatvfs = 16, // fd, buf_ptr, buf_len
Fsync = 17, // fd
Ftruncate = 18, // fd, new len
Futimens = 19, // fd, times_buf, times_len
MmapPrep = 20,
RequestMmap = 21,
Mremap = 22,
Munmap = 23,
Msync = 24, // TODO
Cancel = 25, // @tag
}
impl Opcode {
pub fn try_from_raw(raw: u8) -> Option<Self> {
use Opcode::*;
// TODO: Use a library where this match can be automated.
Some(match raw {
0 => Open,
1 => Rmdir,
2 => Unlink,
3 => Close,
4 => Dup,
5 => Read,
6 => Write,
7 => Fsize,
8 => Fchmod,
9 => Fchown,
10 => Fcntl,
11 => Fevent,
12 => Sendfd,
13 => Fpath,
14 => Frename,
15 => Fstat,
16 => Fstatvfs,
17 => Fsync,
18 => Ftruncate,
19 => Futimens,
20 => MmapPrep,
21 => RequestMmap,
22 => Mremap,
23 => Munmap,
24 => Msync,
25 => Cancel,
_ => return None,
})
}
}