Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions library/std/src/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ impl Error {
#[must_use]
#[inline]
pub fn last_os_error() -> Error {
Error::from_raw_os_error(sys::os::errno())
Error::from_raw_os_error(sys::io::errno())
}

/// Creates a new instance of an [`Error`] from a particular OS error code.
Expand Down Expand Up @@ -1004,7 +1004,7 @@ impl Error {
#[inline]
pub fn kind(&self) -> ErrorKind {
match self.repr.data() {
ErrorData::Os(code) => sys::decode_error_kind(code),
ErrorData::Os(code) => sys::io::decode_error_kind(code),
ErrorData::Custom(c) => c.kind,
ErrorData::Simple(kind) => kind,
ErrorData::SimpleMessage(m) => m.kind,
Expand All @@ -1014,7 +1014,7 @@ impl Error {
#[inline]
pub(crate) fn is_interrupted(&self) -> bool {
match self.repr.data() {
ErrorData::Os(code) => sys::is_interrupted(code),
ErrorData::Os(code) => sys::io::is_interrupted(code),
ErrorData::Custom(c) => c.kind == ErrorKind::Interrupted,
ErrorData::Simple(kind) => kind == ErrorKind::Interrupted,
ErrorData::SimpleMessage(m) => m.kind == ErrorKind::Interrupted,
Expand All @@ -1028,8 +1028,8 @@ impl fmt::Debug for Repr {
ErrorData::Os(code) => fmt
.debug_struct("Os")
.field("code", &code)
.field("kind", &sys::decode_error_kind(code))
.field("message", &sys::os::error_string(code))
.field("kind", &sys::io::decode_error_kind(code))
.field("message", &sys::io::error_string(code))
.finish(),
ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
Expand All @@ -1047,7 +1047,7 @@ impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.repr.data() {
ErrorData::Os(code) => {
let detail = sys::os::error_string(code);
let detail = sys::io::error_string(code);
write!(fmt, "{detail} (os error {code})")
}
ErrorData::Custom(ref c) => c.error.fmt(fmt),
Expand Down
3 changes: 1 addition & 2 deletions library/std/src/io/error/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error};
use crate::assert_matches::assert_matches;
use crate::sys::decode_error_kind;
use crate::sys::os::error_string;
use crate::sys::io::{decode_error_kind, error_string};
use crate::{error, fmt};

#[test]
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/exit_guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ cfg_select! {
// lifetime of the thread. Additionally, accesses to `errno` are
// async-signal-safe, so this function is available in all imaginable
// circumstances.
let this_thread_id = crate::sys::os::errno_location();
let this_thread_id = crate::sys::io::errno_location();
match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
Ok(_) => {
// This is the first thread to call `unique_thread_exit`,
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/fs/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ impl Iterator for ReadDir {
target_os = "wasi",
))]
fn next(&mut self) -> Option<io::Result<DirEntry>> {
use crate::sys::os::{errno, set_errno};
use crate::sys::io::{errno, set_errno};

if self.end_of_stream {
return None;
Expand Down Expand Up @@ -864,7 +864,7 @@ impl Iterator for ReadDir {
/// The downside is that it costs an extra syscall, so we only do it for debug.
#[inline]
pub(crate) fn debug_assert_fd_is_open(fd: RawFd) {
use crate::sys::os::errno;
use crate::sys::io::errno;

// this is similar to assert_unsafe_precondition!() but it doesn't require const
if core::ub_checks::check_library_ub() {
Expand Down
15 changes: 15 additions & 0 deletions library/std/src/sys/io/error/generic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pub fn errno() -> i32 {
0
}

pub fn is_interrupted(_code: i32) -> bool {
false
}

pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Uncategorized
}

pub fn error_string(_errno: i32) -> String {
"operation successful".to_string()
}
35 changes: 35 additions & 0 deletions library/std/src/sys/io/error/hermit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::io;

pub fn errno() -> i32 {
unsafe { hermit_abi::get_errno() }
}

#[inline]
pub fn is_interrupted(errno: i32) -> bool {
errno == hermit_abi::errno::EINTR
}

pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
match errno {
hermit_abi::errno::EACCES => io::ErrorKind::PermissionDenied,
hermit_abi::errno::EADDRINUSE => io::ErrorKind::AddrInUse,
hermit_abi::errno::EADDRNOTAVAIL => io::ErrorKind::AddrNotAvailable,
hermit_abi::errno::EAGAIN => io::ErrorKind::WouldBlock,
hermit_abi::errno::ECONNABORTED => io::ErrorKind::ConnectionAborted,
hermit_abi::errno::ECONNREFUSED => io::ErrorKind::ConnectionRefused,
hermit_abi::errno::ECONNRESET => io::ErrorKind::ConnectionReset,
hermit_abi::errno::EEXIST => io::ErrorKind::AlreadyExists,
hermit_abi::errno::EINTR => io::ErrorKind::Interrupted,
hermit_abi::errno::EINVAL => io::ErrorKind::InvalidInput,
hermit_abi::errno::ENOENT => io::ErrorKind::NotFound,
hermit_abi::errno::ENOTCONN => io::ErrorKind::NotConnected,
hermit_abi::errno::EPERM => io::ErrorKind::PermissionDenied,
hermit_abi::errno::EPIPE => io::ErrorKind::BrokenPipe,
hermit_abi::errno::ETIMEDOUT => io::ErrorKind::TimedOut,
_ => io::ErrorKind::Uncategorized,
}
}

pub fn error_string(errno: i32) -> String {
hermit_abi::error_string(errno).to_string()
}
55 changes: 55 additions & 0 deletions library/std/src/sys/io/error/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
cfg_select! {
target_os = "hermit" => {
mod hermit;
pub use hermit::*;
}
target_os = "motor" => {
mod motor;
pub use motor::*;
}
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx;
pub use sgx::*;
}
target_os = "solid_asp3" => {
mod solid;
pub use solid::*;
}
target_os = "teeos" => {
mod teeos;
pub use teeos::*;
}
target_os = "uefi" => {
mod uefi;
pub use uefi::*;
}
target_family = "unix" => {
mod unix;
pub use unix::*;
}
target_os = "wasi" => {
mod wasi;
pub use wasi::*;
}
target_os = "windows" => {
mod windows;
pub use windows::*;
}
target_os = "xous" => {
mod xous;
pub use xous::*;
}
any(
target_os = "vexos",
target_family = "wasm",
target_os = "zkvm",
) => {
mod generic;
pub use generic::*;
}
}

pub type RawOsError = cfg_select! {
target_os = "uefi" => usize,
_ => i32,
};
67 changes: 67 additions & 0 deletions library/std/src/sys/io/error/motor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use crate::io;
use crate::sys::io::RawOsError;

pub fn errno() -> RawOsError {
// Not used in Motor OS because it is ambiguous: Motor OS
// is micro-kernel-based, and I/O happens via a shared-memory
// ring buffer, so an I/O operation that on a unix is a syscall
// may involve no sycalls on Motor OS at all, or a syscall
// that e.g. waits for a notification from the I/O driver
// (sys-io); and the wait syscall may succeed, but the
// driver may report an I/O error; or a bunch of results
// for several I/O operations, some successful and some
// not.
//
// Also I/O operations in a Motor OS process are handled by a
// separate runtime background/I/O thread, so it is really hard
// to define what "last system error in the current thread"
// actually means.
let error_code: moto_rt::ErrorCode = moto_rt::Error::Unknown.into();
error_code.into()
}

pub fn is_interrupted(_code: io::RawOsError) -> bool {
false // Motor OS doesn't have signals.
}

pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
if code < 0 || code > u16::MAX.into() {
return io::ErrorKind::Uncategorized;
}

let error = moto_rt::Error::from(code as moto_rt::ErrorCode);

match error {
moto_rt::Error::Unspecified => io::ErrorKind::Uncategorized,
moto_rt::Error::Unknown => io::ErrorKind::Uncategorized,
moto_rt::Error::NotReady => io::ErrorKind::WouldBlock,
moto_rt::Error::NotImplemented => io::ErrorKind::Unsupported,
moto_rt::Error::VersionTooHigh => io::ErrorKind::Unsupported,
moto_rt::Error::VersionTooLow => io::ErrorKind::Unsupported,
moto_rt::Error::InvalidArgument => io::ErrorKind::InvalidInput,
moto_rt::Error::OutOfMemory => io::ErrorKind::OutOfMemory,
moto_rt::Error::NotAllowed => io::ErrorKind::PermissionDenied,
moto_rt::Error::NotFound => io::ErrorKind::NotFound,
moto_rt::Error::InternalError => io::ErrorKind::Other,
moto_rt::Error::TimedOut => io::ErrorKind::TimedOut,
moto_rt::Error::AlreadyInUse => io::ErrorKind::AlreadyExists,
moto_rt::Error::UnexpectedEof => io::ErrorKind::UnexpectedEof,
moto_rt::Error::InvalidFilename => io::ErrorKind::InvalidFilename,
moto_rt::Error::NotADirectory => io::ErrorKind::NotADirectory,
moto_rt::Error::BadHandle => io::ErrorKind::InvalidInput,
moto_rt::Error::FileTooLarge => io::ErrorKind::FileTooLarge,
moto_rt::Error::NotConnected => io::ErrorKind::NotConnected,
moto_rt::Error::StorageFull => io::ErrorKind::StorageFull,
moto_rt::Error::InvalidData => io::ErrorKind::InvalidData,
_ => io::ErrorKind::Uncategorized,
}
}

pub fn error_string(errno: RawOsError) -> String {
let error: moto_rt::Error = match errno {
x if x < 0 => moto_rt::Error::Unknown,
x if x > u16::MAX.into() => moto_rt::Error::Unknown,
x => (x as moto_rt::ErrorCode).into(), /* u16 */
};
format!("{}", error)
}
65 changes: 65 additions & 0 deletions library/std/src/sys/io/error/sgx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use fortanix_sgx_abi::{Error, RESULT_SUCCESS};

use crate::io;

pub fn errno() -> i32 {
RESULT_SUCCESS
}

#[inline]
pub fn is_interrupted(code: i32) -> bool {
code == fortanix_sgx_abi::Error::Interrupted as _
}

pub fn decode_error_kind(code: i32) -> io::ErrorKind {
// FIXME: not sure how to make sure all variants of Error are covered
if code == Error::NotFound as _ {
io::ErrorKind::NotFound
} else if code == Error::PermissionDenied as _ {
io::ErrorKind::PermissionDenied
} else if code == Error::ConnectionRefused as _ {
io::ErrorKind::ConnectionRefused
} else if code == Error::ConnectionReset as _ {
io::ErrorKind::ConnectionReset
} else if code == Error::ConnectionAborted as _ {
io::ErrorKind::ConnectionAborted
} else if code == Error::NotConnected as _ {
io::ErrorKind::NotConnected
} else if code == Error::AddrInUse as _ {
io::ErrorKind::AddrInUse
} else if code == Error::AddrNotAvailable as _ {
io::ErrorKind::AddrNotAvailable
} else if code == Error::BrokenPipe as _ {
io::ErrorKind::BrokenPipe
} else if code == Error::AlreadyExists as _ {
io::ErrorKind::AlreadyExists
} else if code == Error::WouldBlock as _ {
io::ErrorKind::WouldBlock
} else if code == Error::InvalidInput as _ {
io::ErrorKind::InvalidInput
} else if code == Error::InvalidData as _ {
io::ErrorKind::InvalidData
} else if code == Error::TimedOut as _ {
io::ErrorKind::TimedOut
} else if code == Error::WriteZero as _ {
io::ErrorKind::WriteZero
} else if code == Error::Interrupted as _ {
io::ErrorKind::Interrupted
} else if code == Error::Other as _ {
io::ErrorKind::Uncategorized
} else if code == Error::UnexpectedEof as _ {
io::ErrorKind::UnexpectedEof
} else {
io::ErrorKind::Uncategorized
}
}

pub fn error_string(errno: i32) -> String {
if errno == RESULT_SUCCESS {
"operation successful".into()
} else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) {
format!("user-specified error {errno:08x}")
} else {
decode_error_kind(errno).as_str().into()
}
}
19 changes: 19 additions & 0 deletions library/std/src/sys/io/error/solid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::io;
use crate::sys::pal::error;

pub fn errno() -> i32 {
0
}

#[inline]
pub fn is_interrupted(code: i32) -> bool {
crate::sys::net::is_interrupted(code)
}

pub fn decode_error_kind(code: i32) -> io::ErrorKind {
error::decode_error_kind(code)
}

pub fn error_string(errno: i32) -> String {
if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") }
}
Loading
Loading