Enforce documentation for ABI crate
This commit is contained in:
parent
5541cc3214
commit
21c610c1a0
67
src/error.rs
67
src/error.rs
@ -1,28 +1,47 @@
|
||||
//! Error definitions and conversion functions
|
||||
use crate::{io::RawFd, primitive_enum};
|
||||
|
||||
primitive_enum!(pub enum Error: u32 {
|
||||
OutOfMemory = 1,
|
||||
InvalidMemoryOperation = 2,
|
||||
AlreadyExists = 3,
|
||||
TimedOut = 4,
|
||||
InvalidArgument = 5,
|
||||
DoesNotExist = 6,
|
||||
IsADirectory = 7,
|
||||
InvalidFile = 8,
|
||||
NotImplemented = 9,
|
||||
NotADirectory = 10,
|
||||
});
|
||||
primitive_enum!(
|
||||
#[doc = "Describes an error reported by the kernel"]
|
||||
pub enum Error: u32 {
|
||||
#[doc = "Kernel ran out of virtual address space or physical memory"]
|
||||
OutOfMemory = 1,
|
||||
#[doc = "Attempted to perform an illegal memory operation"]
|
||||
InvalidMemoryOperation = 2,
|
||||
#[doc = "Entry/file already exists"]
|
||||
AlreadyExists = 3,
|
||||
#[doc = "Operation timed out"]
|
||||
TimedOut = 4,
|
||||
#[doc = "Invalid argument supplied to a kernel function"]
|
||||
InvalidArgument = 5,
|
||||
#[doc = "Entry/file does not exist"]
|
||||
DoesNotExist = 6,
|
||||
#[doc = "A directory found where something else was expected"]
|
||||
IsADirectory = 7,
|
||||
#[doc = "Invalid file descriptor supplied to a kernel function"]
|
||||
InvalidFile = 8,
|
||||
#[doc = "Kernel/driver function is not implemented"]
|
||||
NotImplemented = 9,
|
||||
#[doc = "Entry is not a directory"]
|
||||
NotADirectory = 10,
|
||||
}
|
||||
);
|
||||
|
||||
pub trait FromSyscallResult: Sized {
|
||||
/// Interface for converting between system call result representations
|
||||
pub trait SyscallResult: Sized {
|
||||
/// Converts raw value into a system call result
|
||||
fn from_syscall_result(value: usize) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
pub trait IntoSyscallResult {
|
||||
/// Converts system call result into a raw value
|
||||
fn into_syscall_result(self) -> usize;
|
||||
}
|
||||
|
||||
/// Interface for converting between system call error representations
|
||||
pub trait SyscallError {
|
||||
/// Converts raw value into a system call error
|
||||
fn from_syscall_error(value: usize) -> Self;
|
||||
|
||||
/// Converts system call error into a raw value
|
||||
fn into_syscall_error(self) -> usize;
|
||||
}
|
||||
|
||||
@ -36,16 +55,20 @@ impl SyscallError for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoSyscallResult> IntoSyscallResult for Result<T, Error> {
|
||||
impl<T: SyscallResult> SyscallResult for Result<T, Error> {
|
||||
fn into_syscall_result(self) -> usize {
|
||||
match self {
|
||||
Ok(t) => t.into_syscall_result(),
|
||||
Err(e) => e.into_syscall_error(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_syscall_result(_value: usize) -> Result<Self, Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSyscallResult for () {
|
||||
impl SyscallResult for () {
|
||||
fn from_syscall_result(value: usize) -> Result<Self, Error> {
|
||||
if (value as isize) < 0 {
|
||||
Err(Error::from_syscall_error(value))
|
||||
@ -54,15 +77,13 @@ impl FromSyscallResult for () {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoSyscallResult for () {
|
||||
fn into_syscall_result(self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSyscallResult for usize {
|
||||
impl SyscallResult for usize {
|
||||
fn from_syscall_result(value: usize) -> Result<Self, Error> {
|
||||
if (value as isize) < 0 {
|
||||
Err(Error::from_syscall_error(value))
|
||||
@ -70,16 +91,14 @@ impl FromSyscallResult for usize {
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoSyscallResult for usize {
|
||||
fn into_syscall_result(self) -> usize {
|
||||
assert!((self as isize) >= 0);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSyscallResult for RawFd {
|
||||
impl SyscallResult for RawFd {
|
||||
fn from_syscall_result(value: usize) -> Result<Self, Error> {
|
||||
if (value as isize) < 0 {
|
||||
Err(Error::from_syscall_error(value))
|
||||
@ -88,9 +107,7 @@ impl FromSyscallResult for RawFd {
|
||||
Ok(RawFd(value as u32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoSyscallResult for RawFd {
|
||||
fn into_syscall_result(self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
|
16
src/io.rs
16
src/io.rs
@ -1,24 +1,33 @@
|
||||
//! I/O control data structures
|
||||
use core::fmt;
|
||||
|
||||
/// Raw file descriptor representation
|
||||
#[derive(Clone, Copy, PartialEq, Debug, PartialOrd, Ord, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct RawFd(pub u32);
|
||||
|
||||
/// Describes how a file should be opened
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct OpenFlags(pub u32);
|
||||
|
||||
/// Describes how a mount operation should be performed
|
||||
#[derive(Clone, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct MountOptions {
|
||||
/// Block device to use as a mount source. May be empty when mounting virtual filesystems.
|
||||
pub source: Option<&'static str>,
|
||||
/// Filesystem to use when mounting. Empty means "deduce automatically" and source must be set.
|
||||
pub filesystem: Option<&'static str>,
|
||||
/// Path to a directory to mount the filesystem to
|
||||
pub target: &'static str,
|
||||
}
|
||||
|
||||
/// Describes how an unmount operation should be performed
|
||||
#[derive(Clone, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct UnmountOptions {
|
||||
/// Path to the mountpoint to unmount
|
||||
pub mountpoint: &'static str,
|
||||
}
|
||||
|
||||
@ -26,29 +35,36 @@ const O_READ: u32 = 1 << 0;
|
||||
const O_WRITE: u32 = 1 << 1;
|
||||
|
||||
impl RawFd {
|
||||
/// Default output descriptor of a process
|
||||
pub const STDOUT: Self = Self(1);
|
||||
/// Error output descriptor of a process
|
||||
pub const STDERR: Self = Self(2);
|
||||
}
|
||||
|
||||
impl OpenFlags {
|
||||
/// Constructs an empty open option set
|
||||
pub fn new() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
||||
/// Enables read operation
|
||||
pub const fn read(mut self) -> Self {
|
||||
self.0 |= O_READ;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables write operation
|
||||
pub const fn write(mut self) -> Self {
|
||||
self.0 |= O_WRITE;
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns `true` if [OpenFlags] includes read capability
|
||||
pub const fn is_read(self) -> bool {
|
||||
self.0 & O_READ != 0
|
||||
}
|
||||
|
||||
/// Returns `true` if [OpenFlags] includes write capability
|
||||
pub const fn is_write(self) -> bool {
|
||||
self.0 & O_WRITE != 0
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! Yggdrasil OS user-kernel communication ABI
|
||||
#![no_std]
|
||||
#![feature(trace_macros)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
pub(crate) mod macros;
|
||||
|
||||
|
@ -1,10 +1,15 @@
|
||||
/// Helper macro to define primitive enums with integer reprs, as well as their conversion methods
|
||||
#[macro_export]
|
||||
macro_rules! primitive_enum {
|
||||
($vis:vis enum $name:ident: $repr:ty { $( $variant:ident = $discriminant:literal, )+ }) => {
|
||||
($(#[doc = $enum_doc:expr])? $vis:vis enum $name:ident: $repr:ty {
|
||||
$( $(#[doc = $doc:expr])? $variant:ident = $discriminant:literal, )+
|
||||
}) => {
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[repr($repr)]
|
||||
$(#[doc = $enum_doc])?
|
||||
$vis enum $name {
|
||||
$(
|
||||
$(#[doc = $doc])?
|
||||
$variant = $discriminant
|
||||
),+
|
||||
}
|
||||
|
@ -1,9 +1,16 @@
|
||||
//! Filesystem path definitions and manipulation functions
|
||||
|
||||
/// Parent directory path element
|
||||
pub const PARENT_NAME: &'static str = "..";
|
||||
/// Path element that refers to itself
|
||||
pub const SELF_NAME: &'static str = ".";
|
||||
|
||||
/// String representation of a path separator
|
||||
pub const SEPARATOR_STR: &'static str = "/";
|
||||
/// Character that separates the path elements
|
||||
pub const SEPARATOR: char = '/';
|
||||
|
||||
/// Splits a path, returning the first element and the rest
|
||||
pub fn split_left(path: &str) -> (&str, &str) {
|
||||
if let Some((left, right)) = path.split_once(SEPARATOR) {
|
||||
(left, right.trim_start_matches(SEPARATOR))
|
||||
@ -12,6 +19,7 @@ pub fn split_left(path: &str) -> (&str, &str) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Splits a path, returning the last element and the path preceding it
|
||||
pub fn split_right(path: &str) -> (&str, &str) {
|
||||
if let Some((left, right)) = path.trim_end_matches(SEPARATOR).rsplit_once(SEPARATOR) {
|
||||
(left.trim_end_matches(SEPARATOR), right)
|
||||
|
@ -1,17 +1,32 @@
|
||||
//! System call function definitions
|
||||
use crate::primitive_enum;
|
||||
|
||||
primitive_enum!(pub enum SyscallFunction: usize {
|
||||
Exit = 1,
|
||||
Nanosleep = 2,
|
||||
MapMemory = 3,
|
||||
UnmapMemory = 4,
|
||||
Write = 5,
|
||||
Read = 6,
|
||||
Open = 7,
|
||||
Close = 8,
|
||||
primitive_enum!(
|
||||
#[doc = "Describes a system call issued to the kernel"]
|
||||
pub enum SyscallFunction: usize {
|
||||
#[doc = "Terminate the caller task"]
|
||||
Exit = 1,
|
||||
#[doc = "Suspend the caller task for some time"]
|
||||
Nanosleep = 2,
|
||||
#[doc = "Map a virtual memory region"]
|
||||
MapMemory = 3,
|
||||
#[doc = "Release a virtual memory region"]
|
||||
UnmapMemory = 4,
|
||||
#[doc = "Write data to a file descriptor"]
|
||||
Write = 5,
|
||||
#[doc = "Read data from a file descriptor"]
|
||||
Read = 6,
|
||||
#[doc = "Open a file"]
|
||||
Open = 7,
|
||||
#[doc = "Close a file descriptor"]
|
||||
Close = 8,
|
||||
|
||||
Mount = 101,
|
||||
Unmount = 102,
|
||||
#[doc = "Mount a filesystem"]
|
||||
Mount = 101,
|
||||
#[doc = "Unmount a filesystem"]
|
||||
Unmount = 102,
|
||||
|
||||
DebugTrace = 128,
|
||||
});
|
||||
#[doc = "Print a message to the kernel's debug trace output"]
|
||||
DebugTrace = 128,
|
||||
}
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user