Skip to content

Commit

Permalink
Implement core::error::Error for low level Twizzler error types (#177)
Browse files Browse the repository at this point in the history
* Cleanup error types in twizzler-abi.

* Implement Error for twizzler-runtime-api error types.
  • Loading branch information
dbittman authored Apr 19, 2024
1 parent a620462 commit df047db
Show file tree
Hide file tree
Showing 14 changed files with 396 additions and 612 deletions.
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/lib/twizzler-abi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ talc = { version = "3.0", default-features = false, optional = true }
bitset-core = { version = "0.1", optional = true, default-features = false }
cfg-if = "1.0"
num_enum = { version = "0.7", default-features = false }
thiserror = { package = "thiserror-no-std", version = "2.0", default-features = false }

[dependencies.volatile]
optional = true
Expand Down
1 change: 1 addition & 0 deletions src/lib/twizzler-abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#![feature(rustc_attrs)]
#![feature(asm_const)]
#![feature(linkage)]
#![feature(error_in_core)]
pub mod arch;

#[allow(unused_extern_crates)]
Expand Down
120 changes: 38 additions & 82 deletions src/lib/twizzler-abi/src/syscall/console.rs
Original file line number Diff line number Diff line change
@@ -1,64 +1,41 @@
use bitflags::bitflags;
use core::fmt;
use num_enum::{FromPrimitive, IntoPrimitive};

use crate::arch::syscall::raw_syscall;

use super::{convert_codes_to_result, Syscall};

#[repr(C)]
#[derive(Debug, Clone, Copy)]
#[derive(
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
IntoPrimitive,
FromPrimitive,
thiserror::Error,
)]
#[repr(u64)]
/// Possible errors returned by reading from the kernel console's input.
pub enum KernelConsoleReadError {
/// Unknown error.
#[num_enum(default)]
#[error("unknown error")]
Unknown = 0,
/// Operation would block, but non-blocking was requested.
#[error("would block")]
WouldBlock = 1,
/// Failed to read because there was no input mechanism made available to the kernel.
#[error("no such device")]
NoSuchDevice = 2,
/// The input mechanism had an internal error.
#[error("I/O error")]
IOError = 3,
}

impl KernelConsoleReadError {
fn as_str(&self) -> &str {
match self {
Self::Unknown => "unknown error",
Self::WouldBlock => "operation would block",
Self::NoSuchDevice => "no way to read from kernel console physical device",
Self::IOError => "an IO error occurred",
}
}
}

impl From<KernelConsoleReadError> for u64 {
fn from(x: KernelConsoleReadError) -> Self {
x as u64
}
}

impl From<u64> for KernelConsoleReadError {
fn from(x: u64) -> Self {
match x {
1 => Self::WouldBlock,
2 => Self::NoSuchDevice,
3 => Self::IOError,
_ => Self::Unknown,
}
}
}

impl fmt::Display for KernelConsoleReadError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}

#[cfg(feature = "std")]
impl std::error::Error for KernelConsoleReadError {
fn description(&self) -> &str {
self.as_str()
}
}
impl core::error::Error for KernelConsoleReadError {}

bitflags! {
/// Flags to pass to [sys_kernel_console_read].
Expand Down Expand Up @@ -123,52 +100,31 @@ pub fn sys_kernel_console_read(
convert_codes_to_result(code, val, |c, _| c != 0, |_, v| v as usize, |_, v| v.into())
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
/// Possible errors returned by reading from the kernel console's buffer.
#[derive(
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
IntoPrimitive,
FromPrimitive,
thiserror::Error,
)]
#[repr(u64)]
/// Possible errors returned by reading from the kernel console's input.
pub enum KernelConsoleReadBufferError {
/// Unknown error.
#[num_enum(default)]
#[error("unknown error")]
Unknown = 0,
/// Operation would block, but non-blocking was requested.
#[error("would block")]
WouldBlock = 1,
}

impl KernelConsoleReadBufferError {
fn as_str(&self) -> &str {
match self {
Self::Unknown => "unknown error",
Self::WouldBlock => "operation would block",
}
}
}

impl From<KernelConsoleReadBufferError> for u64 {
fn from(x: KernelConsoleReadBufferError) -> Self {
x as u64
}
}

impl From<u64> for KernelConsoleReadBufferError {
fn from(x: u64) -> Self {
match x {
1 => Self::WouldBlock,
_ => Self::Unknown,
}
}
}

impl fmt::Display for KernelConsoleReadBufferError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}

#[cfg(feature = "std")]
impl std::error::Error for KernelConsoleReadBufferError {
fn description(&self) -> &str {
self.as_str()
}
}
impl core::error::Error for KernelConsoleReadBufferError {}

bitflags! {
/// Flags to pass to [sys_kernel_console_read_buffer].
Expand Down
66 changes: 21 additions & 45 deletions src/lib/twizzler-abi/src/syscall/create.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use core::fmt;

use crate::{arch::syscall::raw_syscall, object::ObjID};
use bitflags::bitflags;
use num_enum::{FromPrimitive, IntoPrimitive};

use super::{convert_codes_to_result, Syscall};

Expand Down Expand Up @@ -125,60 +124,37 @@ impl CreateTieSpec {
}
}

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
#[repr(u32)]
#[derive(
Debug,
Copy,
Clone,
PartialEq,
PartialOrd,
Ord,
Eq,
IntoPrimitive,
FromPrimitive,
thiserror::Error,
)]
#[repr(u64)]
/// Possible error returns for [sys_object_create].
pub enum ObjectCreateError {
/// An unknown error occurred.
#[num_enum(default)]
#[error("unknown error")]
Unknown = 0,
/// One of the arguments was invalid.
#[error("invalid argument")]
InvalidArgument = 1,
/// A source or tie object was not found.
#[error("source or tie object not found")]
ObjectNotFound = 2,
/// The kernel could not handle one of the source ranges.
SourceMisalignment = 3,
}

impl ObjectCreateError {
fn as_str(&self) -> &str {
match self {
Self::Unknown => "an unknown error occurred",
Self::InvalidArgument => "an argument was invalid",
Self::ObjectNotFound => "a referenced object was not found",
Self::SourceMisalignment => "a source specification had an unsatisfiable range",
}
}
}

impl From<ObjectCreateError> for u64 {
fn from(x: ObjectCreateError) -> Self {
x as Self
}
#[error("invalid source directive")]
InvalidSource = 3,
}

impl From<u64> for ObjectCreateError {
fn from(x: u64) -> Self {
match x {
3 => Self::SourceMisalignment,
2 => Self::ObjectNotFound,
1 => Self::InvalidArgument,
_ => Self::Unknown,
}
}
}

impl fmt::Display for ObjectCreateError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}

#[cfg(feature = "std")]
impl std::error::Error for ObjectCreateError {
fn description(&self) -> &str {
self.as_str()
}
}
impl core::error::Error for ObjectCreateError {}

/// Create an object, returning either its ID or an error.
pub fn sys_object_create(
Expand Down
67 changes: 21 additions & 46 deletions src/lib/twizzler-abi/src/syscall/handle.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,43 @@
use core::fmt;

use bitflags::bitflags;
use num_enum::{FromPrimitive, IntoPrimitive};

use crate::{arch::syscall::raw_syscall, object::ObjID};

use super::{convert_codes_to_result, justval, Syscall};
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
#[repr(u32)]
#[derive(
Debug,
Copy,
Clone,
PartialEq,
PartialOrd,
Ord,
Eq,
IntoPrimitive,
FromPrimitive,
thiserror::Error,
)]
#[repr(u64)]
/// Possible error values for [sys_new_handle].
pub enum NewHandleError {
/// An unknown error occurred.
#[num_enum(default)]
#[error("unknown error")]
Unknown = 0,
/// One of the arguments was invalid.
#[error("invalid argument")]
InvalidArgument = 1,
/// The specified object is already a handle.
#[error("object is already a handle")]
AlreadyHandle = 2,
/// The specified object was not found.
#[error("object not found")]
NotFound = 3,
/// The specified handle type is already saturated.
#[error("handle type cannot be used again")]
HandleSaturated = 4,
}

impl NewHandleError {
fn as_str(&self) -> &str {
match self {
Self::Unknown => "an unknown error occurred",
Self::InvalidArgument => "invalid argument",
Self::AlreadyHandle => "object is already a handle",
Self::NotFound => "object was not found",
Self::HandleSaturated => "handle cannot support any more objects",
}
}
}

impl From<NewHandleError> for u64 {
fn from(x: NewHandleError) -> Self {
x as u64
}
}

impl From<u64> for NewHandleError {
fn from(x: u64) -> Self {
match x {
1 => Self::InvalidArgument,
2 => Self::AlreadyHandle,
3 => Self::NotFound,
4 => Self::HandleSaturated,
_ => Self::Unknown,
}
}
}

impl fmt::Display for NewHandleError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}

#[cfg(feature = "std")]
impl std::error::Error for NewHandleError {
fn description(&self) -> &str {
self.as_str()
}
}
impl core::error::Error for NewHandleError {}

/// Possible kernel handle types.
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
Expand Down
Loading

0 comments on commit df047db

Please sign in to comment.