[crates] Seperate error module into errno crate
This commit is contained in:
parent
4027258ec5
commit
5b704984e3
@ -25,6 +25,7 @@ rcore-fs-devfs = { path = "../../deps/sefs/rcore-fs-devfs" }
|
|||||||
resolv-conf = { path = "../../deps/resolv-conf" }
|
resolv-conf = { path = "../../deps/resolv-conf" }
|
||||||
serde = { path = "../../deps/serde-sgx/serde", features = ["derive"] }
|
serde = { path = "../../deps/serde-sgx/serde", features = ["derive"] }
|
||||||
serde_json = { path = "../../deps/serde-json-sgx" }
|
serde_json = { path = "../../deps/serde-json-sgx" }
|
||||||
|
errno = { path = "./crates/errno", features = ["occlum"] }
|
||||||
memoffset = "0.6.1"
|
memoffset = "0.6.1"
|
||||||
scroll = { version = "0.11.0", default-features = false }
|
scroll = { version = "0.11.0", default-features = false }
|
||||||
itertools = { version = "0.10.0", default-features = false, features = ["use_alloc"] }
|
itertools = { version = "0.10.0", default-features = false, features = ["use_alloc"] }
|
||||||
|
265
src/libos/crates/errno/Cargo.lock
generated
Normal file
265
src/libos/crates/errno/Cargo.lock
generated
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"rcore-fs",
|
||||||
|
"serde_json",
|
||||||
|
"sgx_tstd 1.1.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown_tstd"
|
||||||
|
version = "0.12.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "0.4.5"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_tstd 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.149"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rcore-fs"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"spin",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.104"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_tstd 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.40"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"sgx_tstd 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_alloc"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_alloc"
|
||||||
|
version = "1.1.6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_backtrace_sys"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"sgx_build_helper 0.1.0",
|
||||||
|
"sgx_libc 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_backtrace_sys"
|
||||||
|
version = "1.1.6"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"sgx_build_helper 1.1.6",
|
||||||
|
"sgx_libc 1.1.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_build_helper"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_build_helper"
|
||||||
|
version = "1.1.6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_demangle"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_demangle"
|
||||||
|
version = "1.1.6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_libc"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_types 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_libc"
|
||||||
|
version = "1.1.6"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_types 1.1.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_tcrypto"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_types 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_tprotected_fs"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_trts 1.1.0",
|
||||||
|
"sgx_types 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_tprotected_fs"
|
||||||
|
version = "1.1.6"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_trts 1.1.6",
|
||||||
|
"sgx_types 1.1.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_trts"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_libc 1.1.0",
|
||||||
|
"sgx_types 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_trts"
|
||||||
|
version = "1.1.6"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_libc 1.1.6",
|
||||||
|
"sgx_types 1.1.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_tse"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_types 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_tseal"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_tcrypto",
|
||||||
|
"sgx_trts 1.1.0",
|
||||||
|
"sgx_tse",
|
||||||
|
"sgx_types 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_tstd"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_alloc 1.1.0",
|
||||||
|
"sgx_backtrace_sys 1.1.0",
|
||||||
|
"sgx_demangle 1.1.0",
|
||||||
|
"sgx_libc 1.1.0",
|
||||||
|
"sgx_tprotected_fs 1.1.0",
|
||||||
|
"sgx_trts 1.1.0",
|
||||||
|
"sgx_tseal",
|
||||||
|
"sgx_types 1.1.0",
|
||||||
|
"sgx_unwind 0.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_tstd"
|
||||||
|
version = "1.1.6"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown_tstd",
|
||||||
|
"sgx_alloc 1.1.6",
|
||||||
|
"sgx_backtrace_sys 1.1.6",
|
||||||
|
"sgx_demangle 1.1.6",
|
||||||
|
"sgx_libc 1.1.6",
|
||||||
|
"sgx_tprotected_fs 1.1.6",
|
||||||
|
"sgx_trts 1.1.6",
|
||||||
|
"sgx_types 1.1.6",
|
||||||
|
"sgx_unwind 1.1.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_types"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_types"
|
||||||
|
version = "1.1.6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_unwind"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/apache/teaclave-sgx-sdk.git?rev=v1.1.0#71a88b647bb76a16cbc5c3e29403e2afb67f82fd"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_build_helper 0.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sgx_unwind"
|
||||||
|
version = "1.1.6"
|
||||||
|
dependencies = [
|
||||||
|
"sgx_build_helper 1.1.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
19
src/libos/crates/errno/Cargo.toml
Normal file
19
src/libos/crates/errno/Cargo.toml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Tate, Hongliang Tian <tate.thl@antgroup.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
std = []
|
||||||
|
occlum = ["sgx", "serde_json", "rcore-fs"]
|
||||||
|
sgx = ["sgx_tstd"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log = "0.4"
|
||||||
|
serde_json = { path = "../../../../deps/serde-json-sgx", optional = true }
|
||||||
|
sgx_tstd = { path = "../../../../deps/rust-sgx-sdk/sgx_tstd", optional = true }
|
||||||
|
rcore-fs = { path = "../../../../deps/sefs/rcore-fs", optional = true }
|
@ -1,4 +1,9 @@
|
|||||||
use super::*;
|
use alloc::boxed::Box;
|
||||||
|
use alloc::string::String;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
use super::Error;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ErrorBacktrace<'a> {
|
pub struct ErrorBacktrace<'a> {
|
||||||
@ -15,7 +20,7 @@ impl<'a> ErrorBacktrace<'a> {
|
|||||||
|
|
||||||
impl<'a> fmt::Display for ErrorBacktrace<'a> {
|
impl<'a> fmt::Display for ErrorBacktrace<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let error_strings: Vec<String> = self.clone().map(|e| e.to_string()).collect();
|
let error_strings: Vec<String> = self.clone().map(|e| alloc::format!("{}", e)).collect();
|
||||||
let error_backtrace = error_strings.join("\n Caused by ");
|
let error_backtrace = error_strings.join("\n Caused by ");
|
||||||
write!(f, "{}", error_backtrace)
|
write!(f, "{}", error_backtrace)
|
||||||
}
|
}
|
||||||
@ -48,18 +53,3 @@ impl Error {
|
|||||||
ErrorBacktrace::new(self)
|
ErrorBacktrace::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ResultExt<T> {
|
|
||||||
fn cause_err<F>(self, f: F) -> Result<T>
|
|
||||||
where
|
|
||||||
F: FnOnce(&Error) -> Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ResultExt<T> for Result<T> {
|
|
||||||
fn cause_err<F>(self, f: F) -> Result<T>
|
|
||||||
where
|
|
||||||
F: FnOnce(&Error) -> Error,
|
|
||||||
{
|
|
||||||
self.map_err(|old_e| old_e.cause_err(f))
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
use super::*;
|
use core::fmt;
|
||||||
|
|
||||||
/// POSIX errno
|
/// POSIX errno
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
@ -46,7 +46,6 @@ pub enum Errno {
|
|||||||
ENOSYS = 38,
|
ENOSYS = 38,
|
||||||
ENOTEMPTY = 39,
|
ENOTEMPTY = 39,
|
||||||
ELOOP = 40,
|
ELOOP = 40,
|
||||||
EWOULDBLOCK = 41,
|
|
||||||
ENOMSG = 42,
|
ENOMSG = 42,
|
||||||
EIDRM = 43,
|
EIDRM = 43,
|
||||||
ECHRNG = 44,
|
ECHRNG = 44,
|
||||||
@ -145,6 +144,9 @@ const ERRNO_MIN: u32 = Errno::EPERM as u32;
|
|||||||
const ERRNO_MAX: u32 = Errno::EHWPOISON as u32;
|
const ERRNO_MAX: u32 = Errno::EHWPOISON as u32;
|
||||||
|
|
||||||
impl Errno {
|
impl Errno {
|
||||||
|
// EWOULDBLOCK was used on BSD/Sun variants of Unix, and EAGAIN was the AT&T System V error code.
|
||||||
|
// Here we keep same with linux, define EWOULDBLOCK with EAGAIN.
|
||||||
|
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||||
pub(crate) fn as_str(&self) -> &'static str {
|
pub(crate) fn as_str(&self) -> &'static str {
|
||||||
use self::Errno::*;
|
use self::Errno::*;
|
||||||
match *self {
|
match *self {
|
@ -1,4 +1,7 @@
|
|||||||
use super::*;
|
use alloc::boxed::Box;
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
use super::{Errno, ToErrno};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
@ -10,7 +13,7 @@ pub struct Error {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Error__ {
|
enum Error__ {
|
||||||
Embedded((Errno, &'static str)),
|
Embedded((Errno, &'static str)),
|
||||||
Boxed(Box<dyn ToErrno + 'static>),
|
Boxed(Box<dyn ToErrno + Send + 'static>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@ -30,7 +33,7 @@ impl Error {
|
|||||||
|
|
||||||
pub fn boxed<T>(inner: T, location: Option<ErrorLocation>) -> Error
|
pub fn boxed<T>(inner: T, location: Option<ErrorLocation>) -> Error
|
||||||
where
|
where
|
||||||
T: ToErrno + 'static,
|
T: ToErrno + Send + 'static,
|
||||||
{
|
{
|
||||||
Error {
|
Error {
|
||||||
inner: Error__::Boxed(Box::new(inner)),
|
inner: Error__::Boxed(Box::new(inner)),
|
||||||
@ -64,23 +67,6 @@ impl ErrorLocation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for Error {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
self.errno().as_str()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn std::error::Error> {
|
|
||||||
self.cause.as_ref().map(|e| e as &dyn std::error::Error)
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
||||||
self.cause
|
|
||||||
.as_ref()
|
|
||||||
.map(|e| e as &(dyn std::error::Error + 'static))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.inner)?;
|
write!(f, "{}", self.inner)?;
|
||||||
@ -105,3 +91,25 @@ impl fmt::Display for ErrorLocation {
|
|||||||
write!(f, "[line = {}, file = {}]", self.line, self.file)
|
write!(f, "[line = {}, file = {}]", self.line, self.file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "sgx", test, doctest))]
|
||||||
|
mod if_std {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl std::error::Error for Error {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
self.errno().as_str()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cause(&self) -> Option<&dyn std::error::Error> {
|
||||||
|
self.cause.as_ref().map(|e| e as &dyn std::error::Error)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
self.cause
|
||||||
|
.as_ref()
|
||||||
|
.map(|e| e as &(dyn std::error::Error + 'static))
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
204
src/libos/crates/errno/src/lib.rs
Normal file
204
src/libos/crates/errno/src/lib.rs
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
//! User-friendly error handling with build-in support for POSIX errno.
|
||||||
|
//!
|
||||||
|
//! This crate extends Rust's standard error handling with the abilities of
|
||||||
|
//! reporting error locations, providing backtrace information, and unifying
|
||||||
|
//! all types of errors with POSIX errno.
|
||||||
|
//!
|
||||||
|
//! # Motivation
|
||||||
|
//!
|
||||||
|
//! While the built-in error handling mechanism of Rust is undoubtedly superior
|
||||||
|
//! than that of a traditional system programming language (e.g., C/C++), it
|
||||||
|
//! is _not perfect_.
|
||||||
|
//!
|
||||||
|
//! First, trait `std::error::Error` does not provide any means to
|
||||||
|
//! record the location of the source code that triggers an error, leading to
|
||||||
|
//! a slow process of diagnosing errors or bugs.
|
||||||
|
//!
|
||||||
|
//! Second, while the `Error` trait (which has a `cause` method)
|
||||||
|
//! supports backtrace in theory, it is inconvenient---in practice---to implement
|
||||||
|
//! backtrace. This is because the users still need to manually write the concrete
|
||||||
|
//! implementation that stores the cause for every error struct.
|
||||||
|
//!
|
||||||
|
//! Third, one challenging aspect of error handling in Rust is
|
||||||
|
//! dealing with the various types of errors. The standard library
|
||||||
|
//! defines errors like `std::io::Error`, `std::fmt::Error`, `std::str::Utf8Error`, etc.
|
||||||
|
//! Not to mention the error types defined by third-party libraries.
|
||||||
|
//! To make it even worse, we, as OS writers, have to convert all these errors
|
||||||
|
//! into POSIX errno eventually.
|
||||||
|
//!
|
||||||
|
//! To cope with the issues above, this crate extends Rust's standard error
|
||||||
|
//! handling mechanism. Specifically, it aims at the following design goals:
|
||||||
|
//!
|
||||||
|
//! * **Fast diagnose** (e.g., reporting the backtrace and the code location of an error).
|
||||||
|
//! * **First-class POSIX errno** (e.g., every error has an errno).
|
||||||
|
//! * **Zero-overhead abstraction** (e.g., no heap allocation unless absolutely necesary).
|
||||||
|
//! * **Ergonomic grammar** (e.g., use macros to avoid writing code manually).
|
||||||
|
//! * **Compatibility with `no_std`**.
|
||||||
|
//!
|
||||||
|
//! # How to Use
|
||||||
|
//!
|
||||||
|
//! ## Basic Usage
|
||||||
|
//!
|
||||||
|
//! The simplest usage involves just one macro---`errno!`.
|
||||||
|
//! See the sample code below:
|
||||||
|
//! ```rust
|
||||||
|
//! use errno::prelude::*;
|
||||||
|
//!
|
||||||
|
//! fn return_err() -> Result<()> {
|
||||||
|
//! Err(errno!(EINVAL, "the root error"))
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! # fn main() {
|
||||||
|
//! if let Err(e) = return_err() {
|
||||||
|
//! println!("{}", e);
|
||||||
|
//! }
|
||||||
|
//! # }
|
||||||
|
//! ```
|
||||||
|
//! which prints something like
|
||||||
|
//! ```text
|
||||||
|
//! EINVAL (#22, Invalid argument): the root error [line = 45, file = src/lib.rs]
|
||||||
|
//! ```
|
||||||
|
//! Note that the specific line and file of source code that generates the error
|
||||||
|
//! is printed. This facilitates diagnosing errors.
|
||||||
|
//!
|
||||||
|
//! ## Backtrace
|
||||||
|
//!
|
||||||
|
//! A more interesting usage is to print the backtrace of an error. To create
|
||||||
|
//! the chains of errors, `std::result::Result` is extended with a new method
|
||||||
|
//! named `cause_err`. If the result is `Ok`, the method does nothing; otherwise,
|
||||||
|
//! this method executes a user-given closure to output a new error whose cause
|
||||||
|
//! is the error contained in the result. The method consumes the current result
|
||||||
|
//! and generates a new result that contains the new error. The two errors are
|
||||||
|
//! chained. More calls to `cause_err` form deeper backtraces.
|
||||||
|
//!
|
||||||
|
//! See the sample code below:
|
||||||
|
//! ```rust
|
||||||
|
//! use errno::prelude::*;
|
||||||
|
//!
|
||||||
|
//! fn return_err() -> Result<()> {
|
||||||
|
//! Err(errno!(EINVAL, "the root error"))
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! fn cause_err() -> Result<()> {
|
||||||
|
//! return_err()
|
||||||
|
//! .cause_err(|_e| errno!(EIO, "another error"))
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! # fn main() {
|
||||||
|
//! if let Err(e) = cause_err() {
|
||||||
|
//! println!("{}", e.backtrace());
|
||||||
|
//! }
|
||||||
|
//! # }
|
||||||
|
//! ```
|
||||||
|
//! which prints something like
|
||||||
|
//! ```text
|
||||||
|
//! EIO (#5, I/O error): another error [line = 71, file = src/lib.rs]
|
||||||
|
//! Caused by EINVAL (#22, Invalid argument): the root error [line = 68, file = src/lib.rs]
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
|
||||||
|
#![feature(allocator_api)]
|
||||||
|
// Use no_std and alloc crate except when given std feature or during test.
|
||||||
|
#![cfg_attr(not(any(feature = "std", test, doctest)), no_std)]
|
||||||
|
extern crate alloc;
|
||||||
|
// Use Rust SGX SDK's std when given SGX feature.
|
||||||
|
#[cfg(feature = "sgx")]
|
||||||
|
extern crate sgx_tstd as std;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
|
mod backtrace;
|
||||||
|
mod errno;
|
||||||
|
mod error;
|
||||||
|
pub mod prelude;
|
||||||
|
mod result;
|
||||||
|
mod to_errno;
|
||||||
|
|
||||||
|
pub use self::backtrace::ErrorBacktrace;
|
||||||
|
pub use self::errno::*;
|
||||||
|
pub use self::errno::Errno::*;
|
||||||
|
pub use self::error::{Error, ErrorLocation};
|
||||||
|
pub use self::result::{Result, ResultExt};
|
||||||
|
pub use self::to_errno::ToErrno;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! errno {
|
||||||
|
($errno_expr: expr, $error_msg: expr) => {{
|
||||||
|
let inner_error = {
|
||||||
|
let errno: Errno = $errno_expr;
|
||||||
|
let msg: &'static str = $error_msg;
|
||||||
|
(errno, msg)
|
||||||
|
};
|
||||||
|
let error =
|
||||||
|
$crate::Error::embedded(inner_error, Some($crate::ErrorLocation::new(file!(), line!())));
|
||||||
|
error
|
||||||
|
}};
|
||||||
|
($error_expr: expr) => {{
|
||||||
|
let inner_error = $error_expr;
|
||||||
|
let error = $crate::Error::boxed(inner_error, Some($crate::ErrorLocation::new(file!(), line!())));
|
||||||
|
error
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! return_errno {
|
||||||
|
($errno_expr: expr, $error_msg: expr) => {{
|
||||||
|
return Err(errno!($errno_expr, $error_msg));
|
||||||
|
}};
|
||||||
|
($error_expr: expr) => {{
|
||||||
|
return Err(errno!($error_expr));
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// return Err(errno) if libc return -1
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! try_libc {
|
||||||
|
($ret: expr) => {{
|
||||||
|
let ret = unsafe { $ret };
|
||||||
|
if ret < 0 {
|
||||||
|
let errno = unsafe { libc::errno() };
|
||||||
|
return_errno!(Errno::from(errno as u32), "libc error");
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// return Err(errno) if libc return -1
|
||||||
|
// raise SIGPIPE if errno == EPIPE
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! try_libc_may_epipe {
|
||||||
|
($ret: expr) => {{
|
||||||
|
let ret = unsafe { $ret };
|
||||||
|
if ret < 0 {
|
||||||
|
let errno = unsafe { libc::errno() };
|
||||||
|
if errno == Errno::EPIPE as i32 {
|
||||||
|
crate::signal::do_tkill(current!().tid(), crate::signal::SIGPIPE.as_u8() as i32);
|
||||||
|
}
|
||||||
|
return_errno!(Errno::from(errno as u32), "libc error");
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn convert_std_io_error() -> Result<()> {
|
||||||
|
use std::io::{BufWriter, Write};
|
||||||
|
let mut buf_writer = BufWriter::new(Vec::<u8>::new());
|
||||||
|
// std::io::Error can be converted crate::Error implicitly
|
||||||
|
buf_writer.write("foo".as_bytes())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn convert_std_ffi_nul_error() -> Result<()> {
|
||||||
|
use std::ffi::CString;
|
||||||
|
// std::ffi::NulError can be converted crate::Error implicitly
|
||||||
|
let _ = CString::new(b"foo".to_vec())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
3
src/libos/crates/errno/src/prelude.rs
Normal file
3
src/libos/crates/errno/src/prelude.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub use crate::{
|
||||||
|
errno, return_errno, Errno, Errno::*, Error, ErrorLocation, Result, ResultExt, ToErrno,
|
||||||
|
};
|
34
src/libos/crates/errno/src/result.rs
Normal file
34
src/libos/crates/errno/src/result.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use super::{Errno, Error};
|
||||||
|
|
||||||
|
pub type Result<T> = core::result::Result<T, Error>;
|
||||||
|
|
||||||
|
/// Extending `Result` with extra functionalities.
|
||||||
|
pub trait ResultExt<T> {
|
||||||
|
fn cause_err<F>(self, f: F) -> Result<T>
|
||||||
|
where
|
||||||
|
F: FnOnce(&Error) -> Error;
|
||||||
|
|
||||||
|
fn errno(&self) -> Option<Errno>;
|
||||||
|
|
||||||
|
fn has_errno(&self, errno: Errno) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ResultExt<T> for Result<T> {
|
||||||
|
fn cause_err<F>(self, f: F) -> Result<T>
|
||||||
|
where
|
||||||
|
F: FnOnce(&Error) -> Error,
|
||||||
|
{
|
||||||
|
self.map_err(|old_e| old_e.cause_err(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn errno(&self) -> Option<Errno> {
|
||||||
|
match self {
|
||||||
|
Ok(_) => None,
|
||||||
|
Err(e) => Some(e.errno()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_errno(&self, errno: Errno) -> bool {
|
||||||
|
self.errno() == Some(errno)
|
||||||
|
}
|
||||||
|
}
|
138
src/libos/crates/errno/src/to_errno.rs
Normal file
138
src/libos/crates/errno/src/to_errno.rs
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
use super::{Errno, Error};
|
||||||
|
|
||||||
|
pub trait ToErrno: fmt::Display + fmt::Debug {
|
||||||
|
fn errno(&self) -> Errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<T> for Error
|
||||||
|
where
|
||||||
|
T: ToErrno + Send + 'static,
|
||||||
|
{
|
||||||
|
fn from(t: T) -> Error {
|
||||||
|
Error::boxed(t, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToErrno for Errno {
|
||||||
|
fn errno(&self) -> Errno {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToErrno for core::alloc::AllocError {
|
||||||
|
fn errno(&self) -> Errno {
|
||||||
|
Errno::ENOMEM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToErrno for core::alloc::LayoutError {
|
||||||
|
fn errno(&self) -> Errno {
|
||||||
|
Errno::EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToErrno for core::num::ParseIntError {
|
||||||
|
fn errno(&self) -> Errno {
|
||||||
|
Errno::EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "sgx", test, doctest))]
|
||||||
|
mod if_std {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl From<std::io::ErrorKind> for Errno {
|
||||||
|
fn from(kind: std::io::ErrorKind) -> Errno {
|
||||||
|
use std::io::ErrorKind::*;
|
||||||
|
use Errno::*;
|
||||||
|
match kind {
|
||||||
|
NotFound => ENOENT,
|
||||||
|
PermissionDenied => EPERM,
|
||||||
|
ConnectionRefused => ECONNREFUSED,
|
||||||
|
ConnectionReset => ECONNRESET,
|
||||||
|
ConnectionAborted => ECONNABORTED,
|
||||||
|
NotConnected => ENOTCONN,
|
||||||
|
AddrInUse => EADDRINUSE,
|
||||||
|
AddrNotAvailable => EADDRNOTAVAIL,
|
||||||
|
BrokenPipe => EPIPE,
|
||||||
|
AlreadyExists => EEXIST,
|
||||||
|
WouldBlock => Errno::EWOULDBLOCK,
|
||||||
|
InvalidInput => EINVAL,
|
||||||
|
InvalidData => EBADMSG, /* TODO: correct? */
|
||||||
|
TimedOut => ETIMEDOUT,
|
||||||
|
Interrupted => EINTR,
|
||||||
|
WriteZero => EINVAL,
|
||||||
|
UnexpectedEof => EIO,
|
||||||
|
Other => EIO,
|
||||||
|
_ => EIO,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToErrno for std::io::Error {
|
||||||
|
fn errno(&self) -> Errno {
|
||||||
|
Errno::from(self.kind())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToErrno for std::ffi::NulError {
|
||||||
|
fn errno(&self) -> Errno {
|
||||||
|
Errno::EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "occlum")]
|
||||||
|
mod if_occlum {
|
||||||
|
use rcore_fs::dev::DevError;
|
||||||
|
use rcore_fs::vfs::FsError;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl ToErrno for serde_json::Error {
|
||||||
|
fn errno(&self) -> Errno {
|
||||||
|
Errno::EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToErrno for FsError {
|
||||||
|
fn errno(&self) -> Errno {
|
||||||
|
use Errno::*;
|
||||||
|
match *self {
|
||||||
|
FsError::NotSupported => ENOSYS,
|
||||||
|
FsError::NotFile => EISDIR,
|
||||||
|
FsError::IsDir => EISDIR,
|
||||||
|
FsError::NotDir => ENOTDIR,
|
||||||
|
FsError::EntryNotFound => ENOENT,
|
||||||
|
FsError::EntryExist => EEXIST,
|
||||||
|
FsError::NotSameFs => EXDEV,
|
||||||
|
FsError::InvalidParam => EINVAL,
|
||||||
|
FsError::NoDeviceSpace => ENOMEM,
|
||||||
|
FsError::DirRemoved => ENOENT,
|
||||||
|
FsError::DirNotEmpty => ENOTEMPTY,
|
||||||
|
FsError::WrongFs => EINVAL,
|
||||||
|
FsError::DeviceError(_err) => EIO,
|
||||||
|
FsError::SymLoop => ELOOP,
|
||||||
|
FsError::NoDevice => ENXIO,
|
||||||
|
FsError::IOCTLError => EINVAL,
|
||||||
|
FsError::Again => EAGAIN,
|
||||||
|
FsError::Busy => EBUSY,
|
||||||
|
FsError::WrProtected => EROFS,
|
||||||
|
FsError::NoIntegrity => EIO,
|
||||||
|
FsError::PermError => EPERM,
|
||||||
|
FsError::NameTooLong => ENAMETOOLONG,
|
||||||
|
FsError::FileTooBig => EFBIG,
|
||||||
|
FsError::OpNotSupported => EOPNOTSUPP,
|
||||||
|
FsError::NotMountPoint => EINVAL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Error> for DevError {
|
||||||
|
fn from(e: Error) -> Self {
|
||||||
|
DevError(e.errno() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,69 +1,3 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
mod backtrace;
|
pub use errno::{Errno::*, *};
|
||||||
mod errno;
|
|
||||||
mod error;
|
|
||||||
mod to_errno;
|
|
||||||
|
|
||||||
pub use self::backtrace::{ErrorBacktrace, ResultExt};
|
|
||||||
pub use self::errno::Errno;
|
|
||||||
pub use self::errno::Errno::*;
|
|
||||||
pub use self::error::{Error, ErrorLocation};
|
|
||||||
pub use self::to_errno::ToErrno;
|
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
|
||||||
|
|
||||||
macro_rules! errno {
|
|
||||||
($errno_expr: expr, $error_msg: expr) => {{
|
|
||||||
let inner_error = {
|
|
||||||
let errno: Errno = $errno_expr;
|
|
||||||
let msg: &'static str = $error_msg;
|
|
||||||
(errno, msg)
|
|
||||||
};
|
|
||||||
let error = Error::embedded(inner_error, Some(ErrorLocation::new(file!(), line!())));
|
|
||||||
error
|
|
||||||
}};
|
|
||||||
($error_expr: expr) => {{
|
|
||||||
let inner_error = $error_expr;
|
|
||||||
let error = Error::boxed(inner_error, Some(ErrorLocation::new(file!(), line!())));
|
|
||||||
error
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! return_errno {
|
|
||||||
($errno_expr: expr, $error_msg: expr) => {{
|
|
||||||
return Err(errno!($errno_expr, $error_msg));
|
|
||||||
}};
|
|
||||||
($error_expr: expr) => {{
|
|
||||||
return Err(errno!($error_expr));
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
// return Err(errno) if libc return -1
|
|
||||||
macro_rules! try_libc {
|
|
||||||
($ret: expr) => {{
|
|
||||||
let ret = unsafe { $ret };
|
|
||||||
if ret < 0 {
|
|
||||||
let errno = unsafe { libc::errno() };
|
|
||||||
return_errno!(Errno::from(errno as u32), "libc error");
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
// return Err(errno) if libc return -1
|
|
||||||
// raise SIGPIPE if errno == EPIPE
|
|
||||||
macro_rules! try_libc_may_epipe {
|
|
||||||
($ret: expr) => {{
|
|
||||||
let ret = unsafe { $ret };
|
|
||||||
if ret < 0 {
|
|
||||||
let errno = unsafe { libc::errno() };
|
|
||||||
if errno == Errno::EPIPE as i32 {
|
|
||||||
crate::signal::do_tkill(current!().tid(), crate::signal::SIGPIPE.as_u8() as i32);
|
|
||||||
}
|
|
||||||
return_errno!(Errno::from(errno as u32), "libc error");
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
use super::*;
|
|
||||||
|
|
||||||
pub trait ToErrno: fmt::Display + fmt::Debug {
|
|
||||||
fn errno(&self) -> Errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToErrno for Errno {
|
|
||||||
fn errno(&self) -> Errno {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> From<T> for Error
|
|
||||||
where
|
|
||||||
T: ToErrno + 'static,
|
|
||||||
{
|
|
||||||
fn from(t: T) -> Error {
|
|
||||||
Error::boxed(t, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<std::io::ErrorKind> for Errno {
|
|
||||||
fn from(kind: std::io::ErrorKind) -> Errno {
|
|
||||||
use std::io::ErrorKind::*;
|
|
||||||
match kind {
|
|
||||||
NotFound => ENOENT,
|
|
||||||
PermissionDenied => EPERM,
|
|
||||||
ConnectionRefused => ECONNREFUSED,
|
|
||||||
ConnectionReset => ECONNRESET,
|
|
||||||
ConnectionAborted => ECONNABORTED,
|
|
||||||
NotConnected => ENOTCONN,
|
|
||||||
AddrInUse => EADDRINUSE,
|
|
||||||
AddrNotAvailable => EADDRNOTAVAIL,
|
|
||||||
BrokenPipe => EPIPE,
|
|
||||||
AlreadyExists => EEXIST,
|
|
||||||
WouldBlock => EWOULDBLOCK,
|
|
||||||
InvalidInput => EINVAL,
|
|
||||||
InvalidData => EBADMSG, /* TODO: correct? */
|
|
||||||
TimedOut => ETIMEDOUT,
|
|
||||||
Interrupted => EINTR,
|
|
||||||
WriteZero => EINVAL,
|
|
||||||
UnexpectedEof => EIO,
|
|
||||||
Other => EIO,
|
|
||||||
_ => EIO,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToErrno for std::io::Error {
|
|
||||||
fn errno(&self) -> Errno {
|
|
||||||
Errno::from(self.kind())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToErrno for std::ffi::NulError {
|
|
||||||
fn errno(&self) -> Errno {
|
|
||||||
EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToErrno for std::num::ParseIntError {
|
|
||||||
fn errno(&self) -> Errno {
|
|
||||||
EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToErrno for serde_json::Error {
|
|
||||||
fn errno(&self) -> Errno {
|
|
||||||
EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToErrno for rcore_fs::vfs::FsError {
|
|
||||||
fn errno(&self) -> Errno {
|
|
||||||
use rcore_fs::vfs::FsError;
|
|
||||||
match *self {
|
|
||||||
FsError::NotSupported => ENOSYS,
|
|
||||||
FsError::NotFile => EISDIR,
|
|
||||||
FsError::IsDir => EISDIR,
|
|
||||||
FsError::NotDir => ENOTDIR,
|
|
||||||
FsError::EntryNotFound => ENOENT,
|
|
||||||
FsError::EntryExist => EEXIST,
|
|
||||||
FsError::NotSameFs => EXDEV,
|
|
||||||
FsError::InvalidParam => EINVAL,
|
|
||||||
FsError::NoDeviceSpace => ENOMEM,
|
|
||||||
FsError::DirRemoved => ENOENT,
|
|
||||||
FsError::DirNotEmpty => ENOTEMPTY,
|
|
||||||
FsError::WrongFs => EINVAL,
|
|
||||||
FsError::DeviceError(err) => EIO,
|
|
||||||
FsError::SymLoop => ELOOP,
|
|
||||||
FsError::NoDevice => ENXIO,
|
|
||||||
FsError::IOCTLError => EINVAL,
|
|
||||||
FsError::Again => EAGAIN,
|
|
||||||
FsError::Busy => EBUSY,
|
|
||||||
FsError::WrProtected => EROFS,
|
|
||||||
FsError::NoIntegrity => EIO,
|
|
||||||
FsError::PermError => EPERM,
|
|
||||||
FsError::NameTooLong => ENAMETOOLONG,
|
|
||||||
FsError::FileTooBig => EFBIG,
|
|
||||||
FsError::OpNotSupported => EOPNOTSUPP,
|
|
||||||
FsError::NotMountPoint => EINVAL,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToErrno for std::alloc::AllocError {
|
|
||||||
fn errno(&self) -> Errno {
|
|
||||||
ENOMEM
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToErrno for std::alloc::LayoutError {
|
|
||||||
fn errno(&self) -> Errno {
|
|
||||||
EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
@ -321,10 +321,3 @@ impl File for LockedFile {
|
|||||||
Ok(SefsMac(file.get_mac().unwrap()))
|
Ok(SefsMac(file.get_mac().unwrap()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for DevError {
|
|
||||||
fn from(e: Error) -> Self {
|
|
||||||
error!("SGX protected file I/O error: {}", e.backtrace());
|
|
||||||
DevError(e.errno() as i32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user