[crates] Seperate error module into errno crate
This commit is contained in:
		
							parent
							
								
									f9b53dc410
								
							
						
					
					
						commit
						9404da7cf8
					
				| @ -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