Skip to content

Commit 95ea4c5

Browse files
Rollup merge of #150723 - move_pal_error, r=@tgross35
std: move `errno` and related functions into `sys::io` Part of #117276. Currently, `errno` and related functions like `decode_error_kind` are split across `sys::pal` and `sys::pal::os`. This PR moves all of them into a new module inside `sys::io`.
2 parents 4e4bee8 + 0f25fca commit 95ea4c5

File tree

55 files changed

+902
-848
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+902
-848
lines changed

library/std/src/io/error.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ impl Error {
653653
#[must_use]
654654
#[inline]
655655
pub fn last_os_error() -> Error {
656-
Error::from_raw_os_error(sys::os::errno())
656+
Error::from_raw_os_error(sys::io::errno())
657657
}
658658

659659
/// Creates a new instance of an [`Error`] from a particular OS error code.
@@ -1004,7 +1004,7 @@ impl Error {
10041004
#[inline]
10051005
pub fn kind(&self) -> ErrorKind {
10061006
match self.repr.data() {
1007-
ErrorData::Os(code) => sys::decode_error_kind(code),
1007+
ErrorData::Os(code) => sys::io::decode_error_kind(code),
10081008
ErrorData::Custom(c) => c.kind,
10091009
ErrorData::Simple(kind) => kind,
10101010
ErrorData::SimpleMessage(m) => m.kind,
@@ -1014,7 +1014,7 @@ impl Error {
10141014
#[inline]
10151015
pub(crate) fn is_interrupted(&self) -> bool {
10161016
match self.repr.data() {
1017-
ErrorData::Os(code) => sys::is_interrupted(code),
1017+
ErrorData::Os(code) => sys::io::is_interrupted(code),
10181018
ErrorData::Custom(c) => c.kind == ErrorKind::Interrupted,
10191019
ErrorData::Simple(kind) => kind == ErrorKind::Interrupted,
10201020
ErrorData::SimpleMessage(m) => m.kind == ErrorKind::Interrupted,
@@ -1028,8 +1028,8 @@ impl fmt::Debug for Repr {
10281028
ErrorData::Os(code) => fmt
10291029
.debug_struct("Os")
10301030
.field("code", &code)
1031-
.field("kind", &sys::decode_error_kind(code))
1032-
.field("message", &sys::os::error_string(code))
1031+
.field("kind", &sys::io::decode_error_kind(code))
1032+
.field("message", &sys::io::error_string(code))
10331033
.finish(),
10341034
ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
10351035
ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
@@ -1047,7 +1047,7 @@ impl fmt::Display for Error {
10471047
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
10481048
match self.repr.data() {
10491049
ErrorData::Os(code) => {
1050-
let detail = sys::os::error_string(code);
1050+
let detail = sys::io::error_string(code);
10511051
write!(fmt, "{detail} (os error {code})")
10521052
}
10531053
ErrorData::Custom(ref c) => c.error.fmt(fmt),

library/std/src/io/error/tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error};
22
use crate::assert_matches::assert_matches;
3-
use crate::sys::decode_error_kind;
4-
use crate::sys::os::error_string;
3+
use crate::sys::io::{decode_error_kind, error_string};
54
use crate::{error, fmt};
65

76
#[test]

library/std/src/sys/exit_guard.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ cfg_select! {
3434
// lifetime of the thread. Additionally, accesses to `errno` are
3535
// async-signal-safe, so this function is available in all imaginable
3636
// circumstances.
37-
let this_thread_id = crate::sys::os::errno_location();
37+
let this_thread_id = crate::sys::io::errno_location();
3838
match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
3939
Ok(_) => {
4040
// This is the first thread to call `unique_thread_exit`,

library/std/src/sys/fs/unix.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ impl Iterator for ReadDir {
850850
target_os = "wasi",
851851
))]
852852
fn next(&mut self) -> Option<io::Result<DirEntry>> {
853-
use crate::sys::os::{errno, set_errno};
853+
use crate::sys::io::{errno, set_errno};
854854

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

993993
// this is similar to assert_unsafe_precondition!() but it doesn't require const
994994
if core::ub_checks::check_library_ub() {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
pub fn errno() -> i32 {
2+
0
3+
}
4+
5+
pub fn is_interrupted(_code: i32) -> bool {
6+
false
7+
}
8+
9+
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
10+
crate::io::ErrorKind::Uncategorized
11+
}
12+
13+
pub fn error_string(_errno: i32) -> String {
14+
"operation successful".to_string()
15+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::io;
2+
3+
pub fn errno() -> i32 {
4+
unsafe { hermit_abi::get_errno() }
5+
}
6+
7+
#[inline]
8+
pub fn is_interrupted(errno: i32) -> bool {
9+
errno == hermit_abi::errno::EINTR
10+
}
11+
12+
pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
13+
match errno {
14+
hermit_abi::errno::EACCES => io::ErrorKind::PermissionDenied,
15+
hermit_abi::errno::EADDRINUSE => io::ErrorKind::AddrInUse,
16+
hermit_abi::errno::EADDRNOTAVAIL => io::ErrorKind::AddrNotAvailable,
17+
hermit_abi::errno::EAGAIN => io::ErrorKind::WouldBlock,
18+
hermit_abi::errno::ECONNABORTED => io::ErrorKind::ConnectionAborted,
19+
hermit_abi::errno::ECONNREFUSED => io::ErrorKind::ConnectionRefused,
20+
hermit_abi::errno::ECONNRESET => io::ErrorKind::ConnectionReset,
21+
hermit_abi::errno::EEXIST => io::ErrorKind::AlreadyExists,
22+
hermit_abi::errno::EINTR => io::ErrorKind::Interrupted,
23+
hermit_abi::errno::EINVAL => io::ErrorKind::InvalidInput,
24+
hermit_abi::errno::ENOENT => io::ErrorKind::NotFound,
25+
hermit_abi::errno::ENOTCONN => io::ErrorKind::NotConnected,
26+
hermit_abi::errno::EPERM => io::ErrorKind::PermissionDenied,
27+
hermit_abi::errno::EPIPE => io::ErrorKind::BrokenPipe,
28+
hermit_abi::errno::ETIMEDOUT => io::ErrorKind::TimedOut,
29+
_ => io::ErrorKind::Uncategorized,
30+
}
31+
}
32+
33+
pub fn error_string(errno: i32) -> String {
34+
hermit_abi::error_string(errno).to_string()
35+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
cfg_select! {
2+
target_os = "hermit" => {
3+
mod hermit;
4+
pub use hermit::*;
5+
}
6+
target_os = "motor" => {
7+
mod motor;
8+
pub use motor::*;
9+
}
10+
all(target_vendor = "fortanix", target_env = "sgx") => {
11+
mod sgx;
12+
pub use sgx::*;
13+
}
14+
target_os = "solid_asp3" => {
15+
mod solid;
16+
pub use solid::*;
17+
}
18+
target_os = "teeos" => {
19+
mod teeos;
20+
pub use teeos::*;
21+
}
22+
target_os = "uefi" => {
23+
mod uefi;
24+
pub use uefi::*;
25+
}
26+
target_family = "unix" => {
27+
mod unix;
28+
pub use unix::*;
29+
}
30+
target_os = "wasi" => {
31+
mod wasi;
32+
pub use wasi::*;
33+
}
34+
target_os = "windows" => {
35+
mod windows;
36+
pub use windows::*;
37+
}
38+
target_os = "xous" => {
39+
mod xous;
40+
pub use xous::*;
41+
}
42+
any(
43+
target_os = "vexos",
44+
target_family = "wasm",
45+
target_os = "zkvm",
46+
) => {
47+
mod generic;
48+
pub use generic::*;
49+
}
50+
}
51+
52+
pub type RawOsError = cfg_select! {
53+
target_os = "uefi" => usize,
54+
_ => i32,
55+
};
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use crate::io;
2+
use crate::sys::io::RawOsError;
3+
4+
pub fn errno() -> RawOsError {
5+
// Not used in Motor OS because it is ambiguous: Motor OS
6+
// is micro-kernel-based, and I/O happens via a shared-memory
7+
// ring buffer, so an I/O operation that on a unix is a syscall
8+
// may involve no sycalls on Motor OS at all, or a syscall
9+
// that e.g. waits for a notification from the I/O driver
10+
// (sys-io); and the wait syscall may succeed, but the
11+
// driver may report an I/O error; or a bunch of results
12+
// for several I/O operations, some successful and some
13+
// not.
14+
//
15+
// Also I/O operations in a Motor OS process are handled by a
16+
// separate runtime background/I/O thread, so it is really hard
17+
// to define what "last system error in the current thread"
18+
// actually means.
19+
let error_code: moto_rt::ErrorCode = moto_rt::Error::Unknown.into();
20+
error_code.into()
21+
}
22+
23+
pub fn is_interrupted(_code: io::RawOsError) -> bool {
24+
false // Motor OS doesn't have signals.
25+
}
26+
27+
pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
28+
if code < 0 || code > u16::MAX.into() {
29+
return io::ErrorKind::Uncategorized;
30+
}
31+
32+
let error = moto_rt::Error::from(code as moto_rt::ErrorCode);
33+
34+
match error {
35+
moto_rt::Error::Unspecified => io::ErrorKind::Uncategorized,
36+
moto_rt::Error::Unknown => io::ErrorKind::Uncategorized,
37+
moto_rt::Error::NotReady => io::ErrorKind::WouldBlock,
38+
moto_rt::Error::NotImplemented => io::ErrorKind::Unsupported,
39+
moto_rt::Error::VersionTooHigh => io::ErrorKind::Unsupported,
40+
moto_rt::Error::VersionTooLow => io::ErrorKind::Unsupported,
41+
moto_rt::Error::InvalidArgument => io::ErrorKind::InvalidInput,
42+
moto_rt::Error::OutOfMemory => io::ErrorKind::OutOfMemory,
43+
moto_rt::Error::NotAllowed => io::ErrorKind::PermissionDenied,
44+
moto_rt::Error::NotFound => io::ErrorKind::NotFound,
45+
moto_rt::Error::InternalError => io::ErrorKind::Other,
46+
moto_rt::Error::TimedOut => io::ErrorKind::TimedOut,
47+
moto_rt::Error::AlreadyInUse => io::ErrorKind::AlreadyExists,
48+
moto_rt::Error::UnexpectedEof => io::ErrorKind::UnexpectedEof,
49+
moto_rt::Error::InvalidFilename => io::ErrorKind::InvalidFilename,
50+
moto_rt::Error::NotADirectory => io::ErrorKind::NotADirectory,
51+
moto_rt::Error::BadHandle => io::ErrorKind::InvalidInput,
52+
moto_rt::Error::FileTooLarge => io::ErrorKind::FileTooLarge,
53+
moto_rt::Error::NotConnected => io::ErrorKind::NotConnected,
54+
moto_rt::Error::StorageFull => io::ErrorKind::StorageFull,
55+
moto_rt::Error::InvalidData => io::ErrorKind::InvalidData,
56+
_ => io::ErrorKind::Uncategorized,
57+
}
58+
}
59+
60+
pub fn error_string(errno: RawOsError) -> String {
61+
let error: moto_rt::Error = match errno {
62+
x if x < 0 => moto_rt::Error::Unknown,
63+
x if x > u16::MAX.into() => moto_rt::Error::Unknown,
64+
x => (x as moto_rt::ErrorCode).into(), /* u16 */
65+
};
66+
format!("{}", error)
67+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
2+
3+
use crate::io;
4+
5+
pub fn errno() -> i32 {
6+
RESULT_SUCCESS
7+
}
8+
9+
#[inline]
10+
pub fn is_interrupted(code: i32) -> bool {
11+
code == fortanix_sgx_abi::Error::Interrupted as _
12+
}
13+
14+
pub fn decode_error_kind(code: i32) -> io::ErrorKind {
15+
// FIXME: not sure how to make sure all variants of Error are covered
16+
if code == Error::NotFound as _ {
17+
io::ErrorKind::NotFound
18+
} else if code == Error::PermissionDenied as _ {
19+
io::ErrorKind::PermissionDenied
20+
} else if code == Error::ConnectionRefused as _ {
21+
io::ErrorKind::ConnectionRefused
22+
} else if code == Error::ConnectionReset as _ {
23+
io::ErrorKind::ConnectionReset
24+
} else if code == Error::ConnectionAborted as _ {
25+
io::ErrorKind::ConnectionAborted
26+
} else if code == Error::NotConnected as _ {
27+
io::ErrorKind::NotConnected
28+
} else if code == Error::AddrInUse as _ {
29+
io::ErrorKind::AddrInUse
30+
} else if code == Error::AddrNotAvailable as _ {
31+
io::ErrorKind::AddrNotAvailable
32+
} else if code == Error::BrokenPipe as _ {
33+
io::ErrorKind::BrokenPipe
34+
} else if code == Error::AlreadyExists as _ {
35+
io::ErrorKind::AlreadyExists
36+
} else if code == Error::WouldBlock as _ {
37+
io::ErrorKind::WouldBlock
38+
} else if code == Error::InvalidInput as _ {
39+
io::ErrorKind::InvalidInput
40+
} else if code == Error::InvalidData as _ {
41+
io::ErrorKind::InvalidData
42+
} else if code == Error::TimedOut as _ {
43+
io::ErrorKind::TimedOut
44+
} else if code == Error::WriteZero as _ {
45+
io::ErrorKind::WriteZero
46+
} else if code == Error::Interrupted as _ {
47+
io::ErrorKind::Interrupted
48+
} else if code == Error::Other as _ {
49+
io::ErrorKind::Uncategorized
50+
} else if code == Error::UnexpectedEof as _ {
51+
io::ErrorKind::UnexpectedEof
52+
} else {
53+
io::ErrorKind::Uncategorized
54+
}
55+
}
56+
57+
pub fn error_string(errno: i32) -> String {
58+
if errno == RESULT_SUCCESS {
59+
"operation successful".into()
60+
} else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) {
61+
format!("user-specified error {errno:08x}")
62+
} else {
63+
decode_error_kind(errno).as_str().into()
64+
}
65+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use crate::io;
2+
use crate::sys::pal::error;
3+
4+
pub fn errno() -> i32 {
5+
0
6+
}
7+
8+
#[inline]
9+
pub fn is_interrupted(code: i32) -> bool {
10+
crate::sys::net::is_interrupted(code)
11+
}
12+
13+
pub fn decode_error_kind(code: i32) -> io::ErrorKind {
14+
error::decode_error_kind(code)
15+
}
16+
17+
pub fn error_string(errno: i32) -> String {
18+
if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") }
19+
}

0 commit comments

Comments
 (0)