Improved scheme protocol with offset+flags as read/write args
This commit is contained in:
committed by
Jeremy Soller
parent
3e9d68c6b2
commit
ef099bdd2e
@@ -13,6 +13,7 @@ name = "syscall"
|
||||
|
||||
[features]
|
||||
rustc-dep-of-std = ["core", "bitflags/rustc-dep-of-std"]
|
||||
std = []
|
||||
|
||||
[dependencies]
|
||||
bitflags = "2.4"
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user