diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 528eb185df088..b19087e7424a0 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -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. @@ -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, @@ -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, @@ -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(), @@ -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), diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs index 3e4029768eb85..eef44c6ac3b6a 100644 --- a/library/std/src/io/error/tests.rs +++ b/library/std/src/io/error/tests.rs @@ -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] diff --git a/library/std/src/sys/exit_guard.rs b/library/std/src/sys/exit_guard.rs index 00b91842e9dba..e7d7a478a5baa 100644 --- a/library/std/src/sys/exit_guard.rs +++ b/library/std/src/sys/exit_guard.rs @@ -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`, diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 1cc2edd0cf474..716ca9783d1fb 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -726,7 +726,7 @@ impl Iterator for ReadDir { target_os = "wasi", ))] fn next(&mut self) -> Option> { - use crate::sys::os::{errno, set_errno}; + use crate::sys::io::{errno, set_errno}; if self.end_of_stream { return None; @@ -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() { diff --git a/library/std/src/sys/io/error/generic.rs b/library/std/src/sys/io/error/generic.rs new file mode 100644 index 0000000000000..fc70fbaba7e8c --- /dev/null +++ b/library/std/src/sys/io/error/generic.rs @@ -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() +} diff --git a/library/std/src/sys/io/error/hermit.rs b/library/std/src/sys/io/error/hermit.rs new file mode 100644 index 0000000000000..5f42144bb7cfb --- /dev/null +++ b/library/std/src/sys/io/error/hermit.rs @@ -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() +} diff --git a/library/std/src/sys/io/error/mod.rs b/library/std/src/sys/io/error/mod.rs new file mode 100644 index 0000000000000..d7a0b9b4b301d --- /dev/null +++ b/library/std/src/sys/io/error/mod.rs @@ -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, +}; diff --git a/library/std/src/sys/io/error/motor.rs b/library/std/src/sys/io/error/motor.rs new file mode 100644 index 0000000000000..7d612d817cdd7 --- /dev/null +++ b/library/std/src/sys/io/error/motor.rs @@ -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) +} diff --git a/library/std/src/sys/io/error/sgx.rs b/library/std/src/sys/io/error/sgx.rs new file mode 100644 index 0000000000000..8b3e08b0b661b --- /dev/null +++ b/library/std/src/sys/io/error/sgx.rs @@ -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() + } +} diff --git a/library/std/src/sys/io/error/solid.rs b/library/std/src/sys/io/error/solid.rs new file mode 100644 index 0000000000000..8e9503272abbc --- /dev/null +++ b/library/std/src/sys/io/error/solid.rs @@ -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}") } +} diff --git a/library/std/src/sys/io/error/teeos.rs b/library/std/src/sys/io/error/teeos.rs new file mode 100644 index 0000000000000..18826ffc3894f --- /dev/null +++ b/library/std/src/sys/io/error/teeos.rs @@ -0,0 +1,64 @@ +use crate::io; + +pub fn errno() -> i32 { + unsafe { (*libc::__errno_location()) as i32 } +} + +#[inline] +pub fn is_interrupted(errno: i32) -> bool { + errno == libc::EINTR +} + +// Note: code below is 1:1 copied from unix/mod.rs +pub fn decode_error_kind(errno: i32) -> io::ErrorKind { + use io::ErrorKind::*; + match errno as libc::c_int { + libc::E2BIG => ArgumentListTooLong, + libc::EADDRINUSE => AddrInUse, + libc::EADDRNOTAVAIL => AddrNotAvailable, + libc::EBUSY => ResourceBusy, + libc::ECONNABORTED => ConnectionAborted, + libc::ECONNREFUSED => ConnectionRefused, + libc::ECONNRESET => ConnectionReset, + libc::EDEADLK => Deadlock, + libc::EDQUOT => QuotaExceeded, + libc::EEXIST => AlreadyExists, + libc::EFBIG => FileTooLarge, + libc::EHOSTUNREACH => HostUnreachable, + libc::EINTR => Interrupted, + libc::EINVAL => InvalidInput, + libc::EISDIR => IsADirectory, + libc::ELOOP => FilesystemLoop, + libc::ENOENT => NotFound, + libc::ENOMEM => OutOfMemory, + libc::ENOSPC => StorageFull, + libc::ENOSYS => Unsupported, + libc::EMLINK => TooManyLinks, + libc::ENAMETOOLONG => InvalidFilename, + libc::ENETDOWN => NetworkDown, + libc::ENETUNREACH => NetworkUnreachable, + libc::ENOTCONN => NotConnected, + libc::ENOTDIR => NotADirectory, + libc::ENOTEMPTY => DirectoryNotEmpty, + libc::EPIPE => BrokenPipe, + libc::EROFS => ReadOnlyFilesystem, + libc::ESPIPE => NotSeekable, + libc::ESTALE => StaleNetworkFileHandle, + libc::ETIMEDOUT => TimedOut, + libc::ETXTBSY => ExecutableFileBusy, + libc::EXDEV => CrossesDevices, + + libc::EACCES | libc::EPERM => PermissionDenied, + + // These two constants can have the same value on some systems, + // but different values on others, so we can't use a match + // clause + x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock, + + _ => Uncategorized, + } +} + +pub fn error_string(_errno: i32) -> String { + "error string unimplemented".to_string() +} diff --git a/library/std/src/sys/io/error/uefi.rs b/library/std/src/sys/io/error/uefi.rs new file mode 100644 index 0000000000000..bedea240d523b --- /dev/null +++ b/library/std/src/sys/io/error/uefi.rs @@ -0,0 +1,104 @@ +use r_efi::efi::Status; + +use crate::io; + +pub fn errno() -> io::RawOsError { + 0 +} + +pub fn is_interrupted(_code: io::RawOsError) -> bool { + false +} + +pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { + match Status::from_usize(code) { + Status::ALREADY_STARTED + | Status::COMPROMISED_DATA + | Status::CONNECTION_FIN + | Status::CRC_ERROR + | Status::DEVICE_ERROR + | Status::END_OF_MEDIA + | Status::HTTP_ERROR + | Status::ICMP_ERROR + | Status::INCOMPATIBLE_VERSION + | Status::LOAD_ERROR + | Status::MEDIA_CHANGED + | Status::NO_MAPPING + | Status::NO_MEDIA + | Status::NOT_STARTED + | Status::PROTOCOL_ERROR + | Status::PROTOCOL_UNREACHABLE + | Status::TFTP_ERROR + | Status::VOLUME_CORRUPTED => io::ErrorKind::Other, + Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => io::ErrorKind::InvalidData, + Status::ABORTED => io::ErrorKind::ConnectionAborted, + Status::ACCESS_DENIED => io::ErrorKind::PermissionDenied, + Status::BUFFER_TOO_SMALL => io::ErrorKind::FileTooLarge, + Status::CONNECTION_REFUSED => io::ErrorKind::ConnectionRefused, + Status::CONNECTION_RESET => io::ErrorKind::ConnectionReset, + Status::END_OF_FILE => io::ErrorKind::UnexpectedEof, + Status::HOST_UNREACHABLE => io::ErrorKind::HostUnreachable, + Status::INVALID_PARAMETER => io::ErrorKind::InvalidInput, + Status::IP_ADDRESS_CONFLICT => io::ErrorKind::AddrInUse, + Status::NETWORK_UNREACHABLE => io::ErrorKind::NetworkUnreachable, + Status::NO_RESPONSE => io::ErrorKind::HostUnreachable, + Status::NOT_FOUND => io::ErrorKind::NotFound, + Status::NOT_READY => io::ErrorKind::ResourceBusy, + Status::OUT_OF_RESOURCES => io::ErrorKind::OutOfMemory, + Status::SECURITY_VIOLATION => io::ErrorKind::PermissionDenied, + Status::TIMEOUT => io::ErrorKind::TimedOut, + Status::UNSUPPORTED => io::ErrorKind::Unsupported, + Status::VOLUME_FULL => io::ErrorKind::StorageFull, + Status::WRITE_PROTECTED => io::ErrorKind::ReadOnlyFilesystem, + _ => io::ErrorKind::Uncategorized, + } +} + +pub fn error_string(errno: io::RawOsError) -> String { + // Keep the List in Alphabetical Order + // The Messages are taken from UEFI Specification Appendix D - Status Codes + #[rustfmt::skip] + let msg = match Status::from_usize(errno) { + Status::ABORTED => "The operation was aborted.", + Status::ACCESS_DENIED => "Access was denied.", + Status::ALREADY_STARTED => "The protocol has already been started.", + Status::BAD_BUFFER_SIZE => "The buffer was not the proper size for the request.", + Status::BUFFER_TOO_SMALL => "The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs.", + Status::COMPROMISED_DATA => "The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status.", + Status::CONNECTION_FIN => "The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance.", + Status::CONNECTION_REFUSED => "The receiving or transmission operation fails because this connection is refused.", + Status::CONNECTION_RESET => "The connect fails because the connection is reset either by instance itself or the communication peer.", + Status::CRC_ERROR => "A CRC error was detected.", + Status::DEVICE_ERROR => "The physical device reported an error while attempting the operation.", + Status::END_OF_FILE => "The end of the file was reached.", + Status::END_OF_MEDIA => "Beginning or end of media was reached", + Status::HOST_UNREACHABLE => "The remote host is not reachable.", + Status::HTTP_ERROR => "A HTTP error occurred during the network operation.", + Status::ICMP_ERROR => "An ICMP error occurred during the network operation.", + Status::INCOMPATIBLE_VERSION => "The function encountered an internal version that was incompatible with a version requested by the caller.", + Status::INVALID_LANGUAGE => "The language specified was invalid.", + Status::INVALID_PARAMETER => "A parameter was incorrect.", + Status::IP_ADDRESS_CONFLICT => "There is an address conflict address allocation", + Status::LOAD_ERROR => "The image failed to load.", + Status::MEDIA_CHANGED => "The medium in the device has changed since the last access.", + Status::NETWORK_UNREACHABLE => "The network containing the remote host is not reachable.", + Status::NO_MAPPING => "A mapping to a device does not exist.", + Status::NO_MEDIA => "The device does not contain any medium to perform the operation.", + Status::NO_RESPONSE => "The server was not found or did not respond to the request.", + Status::NOT_FOUND => "The item was not found.", + Status::NOT_READY => "There is no data pending upon return.", + Status::NOT_STARTED => "The protocol has not been started.", + Status::OUT_OF_RESOURCES => "A resource has run out.", + Status::PROTOCOL_ERROR => "A protocol error occurred during the network operation.", + Status::PROTOCOL_UNREACHABLE => "An ICMP protocol unreachable error is received.", + Status::SECURITY_VIOLATION => "The function was not performed due to a security violation.", + Status::TFTP_ERROR => "A TFTP error occurred during the network operation.", + Status::TIMEOUT => "The timeout time expired.", + Status::UNSUPPORTED => "The operation is not supported.", + Status::VOLUME_FULL => "There is no more space on the file system.", + Status::VOLUME_CORRUPTED => "An inconstancy was detected on the file system causing the operating to fail.", + Status::WRITE_PROTECTED => "The device cannot be written to.", + _ => return format!("Status: {errno}"), + }; + msg.to_owned() +} diff --git a/library/std/src/sys/io/error/unix.rs b/library/std/src/sys/io/error/unix.rs new file mode 100644 index 0000000000000..b10343b2752c2 --- /dev/null +++ b/library/std/src/sys/io/error/unix.rs @@ -0,0 +1,186 @@ +use crate::ffi::{CStr, c_char, c_int}; +use crate::io; + +unsafe extern "C" { + #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))] + #[cfg_attr( + any( + target_os = "linux", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "l4re", + target_os = "hurd", + ), + link_name = "__errno_location" + )] + #[cfg_attr( + any( + target_os = "netbsd", + target_os = "openbsd", + target_os = "cygwin", + target_os = "android", + target_os = "redox", + target_os = "nuttx", + target_env = "newlib" + ), + link_name = "__errno" + )] + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")] + #[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")] + #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")] + #[cfg_attr(target_os = "haiku", link_name = "_errnop")] + #[cfg_attr(target_os = "aix", link_name = "_Errno")] + // SAFETY: this will always return the same pointer on a given thread. + #[unsafe(ffi_const)] + pub safe fn errno_location() -> *mut c_int; +} + +/// Returns the platform-specific value of errno +#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))] +#[inline] +pub fn errno() -> i32 { + unsafe { (*errno_location()) as i32 } +} + +/// Sets the platform-specific value of errno +// needed for readdir and syscall! +#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))] +#[allow(dead_code)] // but not all target cfgs actually end up using it +#[inline] +pub fn set_errno(e: i32) { + unsafe { *errno_location() = e as c_int } +} + +#[cfg(target_os = "vxworks")] +#[inline] +pub fn errno() -> i32 { + unsafe { libc::errnoGet() } +} + +#[cfg(target_os = "rtems")] +#[inline] +pub fn errno() -> i32 { + unsafe extern "C" { + #[thread_local] + static _tls_errno: c_int; + } + + unsafe { _tls_errno as i32 } +} + +#[cfg(target_os = "dragonfly")] +#[inline] +pub fn errno() -> i32 { + unsafe extern "C" { + #[thread_local] + static errno: c_int; + } + + unsafe { errno as i32 } +} + +#[cfg(target_os = "dragonfly")] +#[allow(dead_code)] +#[inline] +pub fn set_errno(e: i32) { + unsafe extern "C" { + #[thread_local] + static mut errno: c_int; + } + + unsafe { + errno = e; + } +} + +#[inline] +pub fn is_interrupted(errno: i32) -> bool { + errno == libc::EINTR +} + +pub fn decode_error_kind(errno: i32) -> io::ErrorKind { + use io::ErrorKind::*; + match errno as libc::c_int { + libc::E2BIG => ArgumentListTooLong, + libc::EADDRINUSE => AddrInUse, + libc::EADDRNOTAVAIL => AddrNotAvailable, + libc::EBUSY => ResourceBusy, + libc::ECONNABORTED => ConnectionAborted, + libc::ECONNREFUSED => ConnectionRefused, + libc::ECONNRESET => ConnectionReset, + libc::EDEADLK => Deadlock, + libc::EDQUOT => QuotaExceeded, + libc::EEXIST => AlreadyExists, + libc::EFBIG => FileTooLarge, + libc::EHOSTUNREACH => HostUnreachable, + libc::EINTR => Interrupted, + libc::EINVAL => InvalidInput, + libc::EISDIR => IsADirectory, + libc::ELOOP => FilesystemLoop, + libc::ENOENT => NotFound, + libc::ENOMEM => OutOfMemory, + libc::ENOSPC => StorageFull, + libc::ENOSYS => Unsupported, + libc::EMLINK => TooManyLinks, + libc::ENAMETOOLONG => InvalidFilename, + libc::ENETDOWN => NetworkDown, + libc::ENETUNREACH => NetworkUnreachable, + libc::ENOTCONN => NotConnected, + libc::ENOTDIR => NotADirectory, + #[cfg(not(target_os = "aix"))] + libc::ENOTEMPTY => DirectoryNotEmpty, + libc::EPIPE => BrokenPipe, + libc::EROFS => ReadOnlyFilesystem, + libc::ESPIPE => NotSeekable, + libc::ESTALE => StaleNetworkFileHandle, + libc::ETIMEDOUT => TimedOut, + libc::ETXTBSY => ExecutableFileBusy, + libc::EXDEV => CrossesDevices, + libc::EINPROGRESS => InProgress, + libc::EOPNOTSUPP => Unsupported, + + libc::EACCES | libc::EPERM => PermissionDenied, + + // These two constants can have the same value on some systems, + // but different values on others, so we can't use a match + // clause + x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock, + + _ => Uncategorized, + } +} + +/// Gets a detailed string description for the given error number. +pub fn error_string(errno: i32) -> String { + const TMPBUF_SZ: usize = 128; + + unsafe extern "C" { + #[cfg_attr( + all( + any( + target_os = "linux", + target_os = "hurd", + target_env = "newlib", + target_os = "cygwin" + ), + not(target_env = "ohos") + ), + link_name = "__xpg_strerror_r" + )] + fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int; + } + + let mut buf = [0 as c_char; TMPBUF_SZ]; + + let p = buf.as_mut_ptr(); + unsafe { + if strerror_r(errno as c_int, p, buf.len()) < 0 { + panic!("strerror_r failure"); + } + + let p = p as *const _; + // We can't always expect a UTF-8 environment. When we don't get that luxury, + // it's better to give a low-quality error message than none at all. + String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into() + } +} diff --git a/library/std/src/sys/io/error/wasi.rs b/library/std/src/sys/io/error/wasi.rs new file mode 100644 index 0000000000000..719fc0c900adc --- /dev/null +++ b/library/std/src/sys/io/error/wasi.rs @@ -0,0 +1,80 @@ +use crate::ffi::CStr; +use crate::io as std_io; + +unsafe extern "C" { + #[thread_local] + #[link_name = "errno"] + static mut libc_errno: libc::c_int; +} + +pub fn errno() -> i32 { + unsafe { libc_errno as i32 } +} + +pub fn set_errno(val: i32) { + unsafe { + libc_errno = val; + } +} + +#[inline] +pub fn is_interrupted(errno: i32) -> bool { + errno == libc::EINTR +} + +pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { + use std_io::ErrorKind::*; + match errno as libc::c_int { + libc::E2BIG => ArgumentListTooLong, + libc::EADDRINUSE => AddrInUse, + libc::EADDRNOTAVAIL => AddrNotAvailable, + libc::EBUSY => ResourceBusy, + libc::ECONNABORTED => ConnectionAborted, + libc::ECONNREFUSED => ConnectionRefused, + libc::ECONNRESET => ConnectionReset, + libc::EDEADLK => Deadlock, + libc::EDQUOT => QuotaExceeded, + libc::EEXIST => AlreadyExists, + libc::EFBIG => FileTooLarge, + libc::EHOSTUNREACH => HostUnreachable, + libc::EINTR => Interrupted, + libc::EINVAL => InvalidInput, + libc::EISDIR => IsADirectory, + libc::ELOOP => FilesystemLoop, + libc::ENOENT => NotFound, + libc::ENOMEM => OutOfMemory, + libc::ENOSPC => StorageFull, + libc::ENOSYS => Unsupported, + libc::EMLINK => TooManyLinks, + libc::ENAMETOOLONG => InvalidFilename, + libc::ENETDOWN => NetworkDown, + libc::ENETUNREACH => NetworkUnreachable, + libc::ENOTCONN => NotConnected, + libc::ENOTDIR => NotADirectory, + libc::EPIPE => BrokenPipe, + libc::EROFS => ReadOnlyFilesystem, + libc::ESPIPE => NotSeekable, + libc::ESTALE => StaleNetworkFileHandle, + libc::ETIMEDOUT => TimedOut, + libc::ETXTBSY => ExecutableFileBusy, + libc::EXDEV => CrossesDevices, + libc::EINPROGRESS => InProgress, + libc::EOPNOTSUPP => Unsupported, + libc::EACCES | libc::EPERM => PermissionDenied, + libc::EWOULDBLOCK => WouldBlock, + + _ => Uncategorized, + } +} + +pub fn error_string(errno: i32) -> String { + let mut buf = [0 as libc::c_char; 1024]; + + let p = buf.as_mut_ptr(); + unsafe { + if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 { + panic!("strerror_r failure"); + } + str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned() + } +} diff --git a/library/std/src/sys/io/error/windows.rs b/library/std/src/sys/io/error/windows.rs new file mode 100644 index 0000000000000..e02197ac67756 --- /dev/null +++ b/library/std/src/sys/io/error/windows.rs @@ -0,0 +1,140 @@ +use crate::sys::pal::{api, c}; +use crate::{io, ptr}; + +pub fn errno() -> i32 { + api::get_last_error().code as i32 +} + +#[inline] +pub fn is_interrupted(_errno: i32) -> bool { + false +} + +pub fn decode_error_kind(errno: i32) -> io::ErrorKind { + use io::ErrorKind::*; + + match errno as u32 { + c::ERROR_ACCESS_DENIED => return PermissionDenied, + c::ERROR_ALREADY_EXISTS => return AlreadyExists, + c::ERROR_FILE_EXISTS => return AlreadyExists, + c::ERROR_BROKEN_PIPE => return BrokenPipe, + c::ERROR_FILE_NOT_FOUND + | c::ERROR_PATH_NOT_FOUND + | c::ERROR_INVALID_DRIVE + | c::ERROR_BAD_NETPATH + | c::ERROR_BAD_NET_NAME => return NotFound, + c::ERROR_NO_DATA => return BrokenPipe, + c::ERROR_INVALID_NAME | c::ERROR_BAD_PATHNAME => return InvalidFilename, + c::ERROR_INVALID_PARAMETER => return InvalidInput, + c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory, + c::ERROR_SEM_TIMEOUT + | c::WAIT_TIMEOUT + | c::ERROR_DRIVER_CANCEL_TIMEOUT + | c::ERROR_OPERATION_ABORTED + | c::ERROR_SERVICE_REQUEST_TIMEOUT + | c::ERROR_COUNTER_TIMEOUT + | c::ERROR_TIMEOUT + | c::ERROR_RESOURCE_CALL_TIMED_OUT + | c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT + | c::ERROR_CTX_CLIENT_QUERY_TIMEOUT + | c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT + | c::ERROR_DS_TIMELIMIT_EXCEEDED + | c::DNS_ERROR_RECORD_TIMED_OUT + | c::ERROR_IPSEC_IKE_TIMED_OUT + | c::ERROR_RUNLEVEL_SWITCH_TIMEOUT + | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return TimedOut, + c::ERROR_CALL_NOT_IMPLEMENTED => return Unsupported, + c::ERROR_HOST_UNREACHABLE => return HostUnreachable, + c::ERROR_NETWORK_UNREACHABLE => return NetworkUnreachable, + c::ERROR_DIRECTORY => return NotADirectory, + c::ERROR_DIRECTORY_NOT_SUPPORTED => return IsADirectory, + c::ERROR_DIR_NOT_EMPTY => return DirectoryNotEmpty, + c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem, + c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull, + c::ERROR_SEEK_ON_DEVICE => return NotSeekable, + c::ERROR_DISK_QUOTA_EXCEEDED => return QuotaExceeded, + c::ERROR_FILE_TOO_LARGE => return FileTooLarge, + c::ERROR_BUSY => return ResourceBusy, + c::ERROR_POSSIBLE_DEADLOCK => return Deadlock, + c::ERROR_NOT_SAME_DEVICE => return CrossesDevices, + c::ERROR_TOO_MANY_LINKS => return TooManyLinks, + c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename, + c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop, + _ => {} + } + + match errno { + c::WSAEACCES => PermissionDenied, + c::WSAEADDRINUSE => AddrInUse, + c::WSAEADDRNOTAVAIL => AddrNotAvailable, + c::WSAECONNABORTED => ConnectionAborted, + c::WSAECONNREFUSED => ConnectionRefused, + c::WSAECONNRESET => ConnectionReset, + c::WSAEINVAL => InvalidInput, + c::WSAENOTCONN => NotConnected, + c::WSAEWOULDBLOCK => WouldBlock, + c::WSAETIMEDOUT => TimedOut, + c::WSAEHOSTUNREACH => HostUnreachable, + c::WSAENETDOWN => NetworkDown, + c::WSAENETUNREACH => NetworkUnreachable, + c::WSAEDQUOT => QuotaExceeded, + + _ => Uncategorized, + } +} + +/// Gets a detailed string description for the given error number. +pub fn error_string(mut errnum: i32) -> String { + let mut buf = [0 as c::WCHAR; 2048]; + + unsafe { + let mut module = ptr::null_mut(); + let mut flags = 0; + + // NTSTATUS errors may be encoded as HRESULT, which may returned from + // GetLastError. For more information about Windows error codes, see + // `[MS-ERREF]`: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548a + if (errnum & c::FACILITY_NT_BIT as i32) != 0 { + // format according to https://support.microsoft.com/en-us/help/259693 + const NTDLL_DLL: &[u16] = &[ + 'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _, + 'L' as _, 0, + ]; + module = c::GetModuleHandleW(NTDLL_DLL.as_ptr()); + + if !module.is_null() { + errnum ^= c::FACILITY_NT_BIT as i32; + flags = c::FORMAT_MESSAGE_FROM_HMODULE; + } + } + + let res = c::FormatMessageW( + flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS, + module, + errnum as u32, + 0, + buf.as_mut_ptr(), + buf.len() as u32, + ptr::null(), + ) as usize; + if res == 0 { + // Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId, + let fm_err = errno(); + return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})"); + } + + match String::from_utf16(&buf[..res]) { + Ok(mut msg) => { + // Trim trailing CRLF inserted by FormatMessageW + let len = msg.trim_end().len(); + msg.truncate(len); + msg + } + Err(..) => format!( + "OS Error {} (FormatMessageW() returned \ + invalid UTF-16)", + errnum + ), + } + } +} diff --git a/library/std/src/sys/io/error/xous.rs b/library/std/src/sys/io/error/xous.rs new file mode 100644 index 0000000000000..2e9ea8e4f0928 --- /dev/null +++ b/library/std/src/sys/io/error/xous.rs @@ -0,0 +1,17 @@ +use crate::os::xous::ffi::Error as XousError; + +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 { + Into::::into(errno).to_string() +} diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs index 4a5d6f8e27f25..b3587ab63696a 100644 --- a/library/std/src/sys/io/mod.rs +++ b/library/std/src/sys/io/mod.rs @@ -1,5 +1,7 @@ #![forbid(unsafe_op_in_unsafe_fn)] +mod error; + mod io_slice { cfg_select! { any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty", target_os = "wasi") => { @@ -48,6 +50,19 @@ mod is_terminal { mod kernel_copy; +#[cfg_attr(not(target_os = "linux"), allow(unused_imports))] +#[cfg(all( + target_family = "unix", + not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")) +))] +pub use error::errno_location; +#[cfg_attr(not(target_os = "linux"), allow(unused_imports))] +#[cfg(any( + all(target_family = "unix", not(any(target_os = "vxworks", target_os = "rtems"))), + target_os = "wasi", +))] +pub use error::set_errno; +pub use error::{RawOsError, decode_error_kind, errno, error_string, is_interrupted}; pub use io_slice::{IoSlice, IoSliceMut}; pub use is_terminal::is_terminal; pub use kernel_copy::{CopyState, kernel_copy}; @@ -55,8 +70,3 @@ pub use kernel_copy::{CopyState, kernel_copy}; // Bare metal platforms usually have very small amounts of RAM // (in the order of hundreds of KB) pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 }; - -pub type RawOsError = cfg_select! { - target_os = "uefi" => usize, - _ => i32, -}; diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index d09ba97cfe012..5e20c0ffdfa6a 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -151,7 +151,7 @@ impl Socket { loop { let result = unsafe { libc::connect(self.as_raw_fd(), addr.as_ptr(), len) }; if result.is_minus_one() { - let err = crate::sys::os::errno(); + let err = crate::sys::io::errno(); match err { libc::EINTR => continue, libc::EISCONN => return Ok(()), diff --git a/library/std/src/sys/net/hostname/unix.rs b/library/std/src/sys/net/hostname/unix.rs index bc6fa82a38f0d..d444182f3fde6 100644 --- a/library/std/src/sys/net/hostname/unix.rs +++ b/library/std/src/sys/net/hostname/unix.rs @@ -1,7 +1,7 @@ use crate::ffi::OsString; use crate::io; use crate::os::unix::ffi::OsStringExt; -use crate::sys::pal::os::errno; +use crate::sys::io::errno; pub fn hostname() -> io::Result { // Query the system for the maximum host name length. diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index 0e1328a7972f8..db64f8d882e24 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -75,32 +75,6 @@ pub unsafe extern "C" fn runtime_entry( } } -#[inline] -pub(crate) 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, - } -} - #[doc(hidden)] pub trait IsNegative { fn is_negative(&self) -> bool; @@ -131,12 +105,7 @@ impl IsNegative for i32 { impl_is_negative! { i8 i16 i64 isize } pub fn cvt(t: T) -> io::Result { - if t.is_negative() { - let e = decode_error_kind(t.negate()); - Err(io::Error::from(e)) - } else { - Ok(t) - } + if t.is_negative() { Err(io::Error::from_raw_os_error(t.negate())) } else { Ok(t) } } pub fn cvt_r(mut f: F) -> io::Result diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs index 9681964ed9b2f..48a7cdcd2f763 100644 --- a/library/std/src/sys/pal/hermit/os.rs +++ b/library/std/src/sys/pal/hermit/os.rs @@ -5,14 +5,6 @@ use crate::path::{self, PathBuf}; use crate::sys::unsupported; use crate::{fmt, io}; -pub fn errno() -> i32 { - unsafe { hermit_abi::get_errno() } -} - -pub fn error_string(errno: i32) -> String { - hermit_abi::error_string(errno).to_string() -} - pub fn getcwd() -> io::Result { Ok(PathBuf::from("/")) } diff --git a/library/std/src/sys/pal/motor/mod.rs b/library/std/src/sys/pal/motor/mod.rs index 016fbe5c154c9..e5b99cea01d55 100644 --- a/library/std/src/sys/pal/motor/mod.rs +++ b/library/std/src/sys/pal/motor/mod.rs @@ -44,45 +44,6 @@ pub fn unsupported_err() -> io::Error { io::Error::UNSUPPORTED_PLATFORM } -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 { - use moto_rt::error::*; - - 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 abort_internal() -> ! { core::intrinsics::abort(); } diff --git a/library/std/src/sys/pal/motor/os.rs b/library/std/src/sys/pal/motor/os.rs index 0367c905b4535..cdf66e3958dbe 100644 --- a/library/std/src/sys/pal/motor/os.rs +++ b/library/std/src/sys/pal/motor/os.rs @@ -4,37 +4,8 @@ use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; use crate::os::motor::ffi::OsStrExt; use crate::path::{self, PathBuf}; -use crate::sys::io::RawOsError; use crate::{fmt, io}; -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 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) -} - pub fn getcwd() -> io::Result { moto_rt::fs::getcwd().map(PathBuf::from).map_err(map_motor_error) } diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index a067480508c7c..7f1c81a0ff7bf 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -54,56 +54,6 @@ pub fn sgx_ineffective(v: T) -> io::Result { } } -#[inline] -pub fn is_interrupted(code: i32) -> bool { - code == fortanix_sgx_abi::Error::Interrupted as _ -} - -pub fn decode_error_kind(code: i32) -> io::ErrorKind { - use fortanix_sgx_abi::Error; - - // 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 abort_internal() -> ! { abi::usercalls::exit(true) } diff --git a/library/std/src/sys/pal/sgx/os.rs b/library/std/src/sys/pal/sgx/os.rs index 28d79963ac874..ba47af7ff88d7 100644 --- a/library/std/src/sys/pal/sgx/os.rs +++ b/library/std/src/sys/pal/sgx/os.rs @@ -1,25 +1,9 @@ -use fortanix_sgx_abi::{Error, RESULT_SUCCESS}; - use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; use crate::path::{self, PathBuf}; -use crate::sys::{decode_error_kind, sgx_ineffective, unsupported}; +use crate::sys::{sgx_ineffective, unsupported}; use crate::{fmt, io}; -pub fn errno() -> i32 { - RESULT_SUCCESS -} - -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() - } -} - pub fn getcwd() -> io::Result { unsupported() } diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index 01477c7dc5e9b..4eec12dacd7ca 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -38,15 +38,6 @@ pub fn unsupported_err() -> io::Error { io::Error::UNSUPPORTED_PLATFORM } -#[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) -} - #[inline] pub fn abort_internal() -> ! { unsafe { libc::abort() } diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs index cb6e2cbceae6c..c336a1042da40 100644 --- a/library/std/src/sys/pal/solid/os.rs +++ b/library/std/src/sys/pal/solid/os.rs @@ -1,4 +1,4 @@ -use super::{error, itron, unsupported}; +use super::{itron, unsupported}; use crate::ffi::{OsStr, OsString}; use crate::path::{self, PathBuf}; use crate::{fmt, io}; @@ -11,14 +11,6 @@ impl itron::error::ItronError { } } -pub fn errno() -> i32 { - 0 -} - -pub fn error_string(errno: i32) -> String { - if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") } -} - pub fn getcwd() -> io::Result { unsupported() } diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 627096b11c388..d40c10663fd17 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -38,61 +38,6 @@ pub unsafe fn cleanup() { // stack_overflow::cleanup(); } -#[inline] -pub(crate) fn is_interrupted(errno: i32) -> bool { - errno == libc::EINTR -} - -// Note: code below is 1:1 copied from unix/mod.rs -pub fn decode_error_kind(errno: i32) -> io::ErrorKind { - use io::ErrorKind::*; - match errno as libc::c_int { - libc::E2BIG => ArgumentListTooLong, - libc::EADDRINUSE => AddrInUse, - libc::EADDRNOTAVAIL => AddrNotAvailable, - libc::EBUSY => ResourceBusy, - libc::ECONNABORTED => ConnectionAborted, - libc::ECONNREFUSED => ConnectionRefused, - libc::ECONNRESET => ConnectionReset, - libc::EDEADLK => Deadlock, - libc::EDQUOT => QuotaExceeded, - libc::EEXIST => AlreadyExists, - libc::EFBIG => FileTooLarge, - libc::EHOSTUNREACH => HostUnreachable, - libc::EINTR => Interrupted, - libc::EINVAL => InvalidInput, - libc::EISDIR => IsADirectory, - libc::ELOOP => FilesystemLoop, - libc::ENOENT => NotFound, - libc::ENOMEM => OutOfMemory, - libc::ENOSPC => StorageFull, - libc::ENOSYS => Unsupported, - libc::EMLINK => TooManyLinks, - libc::ENAMETOOLONG => InvalidFilename, - libc::ENETDOWN => NetworkDown, - libc::ENETUNREACH => NetworkUnreachable, - libc::ENOTCONN => NotConnected, - libc::ENOTDIR => NotADirectory, - libc::ENOTEMPTY => DirectoryNotEmpty, - libc::EPIPE => BrokenPipe, - libc::EROFS => ReadOnlyFilesystem, - libc::ESPIPE => NotSeekable, - libc::ESTALE => StaleNetworkFileHandle, - libc::ETIMEDOUT => TimedOut, - libc::ETXTBSY => ExecutableFileBusy, - libc::EXDEV => CrossesDevices, - - libc::EACCES | libc::EPERM => PermissionDenied, - - // These two constants can have the same value on some systems, - // but different values on others, so we can't use a match - // clause - x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock, - - _ => Uncategorized, - } -} - #[doc(hidden)] pub trait IsMinusOne { fn is_minus_one(&self) -> bool; diff --git a/library/std/src/sys/pal/teeos/os.rs b/library/std/src/sys/pal/teeos/os.rs index 512b3e2885bf0..a4b1d3c6ae670 100644 --- a/library/std/src/sys/pal/teeos/os.rs +++ b/library/std/src/sys/pal/teeos/os.rs @@ -7,10 +7,6 @@ use crate::ffi::{OsStr, OsString}; use crate::path::PathBuf; use crate::{fmt, io, path}; -pub fn errno() -> i32 { - unsafe { (*libc::__errno_location()) as i32 } -} - // Hardcoded to return 4096, since `sysconf` is only implemented as a stub. pub fn page_size() -> usize { // unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }; @@ -19,10 +15,6 @@ pub fn page_size() -> usize { // Everything below are stubs and copied from unsupported.rs -pub fn error_string(_errno: i32) -> String { - "error string unimplemented".to_string() -} - pub fn getcwd() -> io::Result { unsupported() } diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index e2f99d6751f5e..b181d78c2345a 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -83,52 +83,6 @@ pub const fn unsupported_err() -> io::Error { io::const_error!(io::ErrorKind::Unsupported, "operation not supported on UEFI") } -pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { - use r_efi::efi::Status; - - match r_efi::efi::Status::from_usize(code) { - Status::ALREADY_STARTED - | Status::COMPROMISED_DATA - | Status::CONNECTION_FIN - | Status::CRC_ERROR - | Status::DEVICE_ERROR - | Status::END_OF_MEDIA - | Status::HTTP_ERROR - | Status::ICMP_ERROR - | Status::INCOMPATIBLE_VERSION - | Status::LOAD_ERROR - | Status::MEDIA_CHANGED - | Status::NO_MAPPING - | Status::NO_MEDIA - | Status::NOT_STARTED - | Status::PROTOCOL_ERROR - | Status::PROTOCOL_UNREACHABLE - | Status::TFTP_ERROR - | Status::VOLUME_CORRUPTED => io::ErrorKind::Other, - Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => io::ErrorKind::InvalidData, - Status::ABORTED => io::ErrorKind::ConnectionAborted, - Status::ACCESS_DENIED => io::ErrorKind::PermissionDenied, - Status::BUFFER_TOO_SMALL => io::ErrorKind::FileTooLarge, - Status::CONNECTION_REFUSED => io::ErrorKind::ConnectionRefused, - Status::CONNECTION_RESET => io::ErrorKind::ConnectionReset, - Status::END_OF_FILE => io::ErrorKind::UnexpectedEof, - Status::HOST_UNREACHABLE => io::ErrorKind::HostUnreachable, - Status::INVALID_PARAMETER => io::ErrorKind::InvalidInput, - Status::IP_ADDRESS_CONFLICT => io::ErrorKind::AddrInUse, - Status::NETWORK_UNREACHABLE => io::ErrorKind::NetworkUnreachable, - Status::NO_RESPONSE => io::ErrorKind::HostUnreachable, - Status::NOT_FOUND => io::ErrorKind::NotFound, - Status::NOT_READY => io::ErrorKind::ResourceBusy, - Status::OUT_OF_RESOURCES => io::ErrorKind::OutOfMemory, - Status::SECURITY_VIOLATION => io::ErrorKind::PermissionDenied, - Status::TIMEOUT => io::ErrorKind::TimedOut, - Status::UNSUPPORTED => io::ErrorKind::Unsupported, - Status::VOLUME_FULL => io::ErrorKind::StorageFull, - Status::WRITE_PROTECTED => io::ErrorKind::ReadOnlyFilesystem, - _ => io::ErrorKind::Uncategorized, - } -} - pub fn abort_internal() -> ! { if let Some(exit_boot_service_event) = NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire)) @@ -158,7 +112,3 @@ pub fn abort_internal() -> ! { extern "efiapi" fn exit_boot_service_handler(_e: r_efi::efi::Event, _ctx: *mut crate::ffi::c_void) { uefi::env::disable_boot_services(); } - -pub fn is_interrupted(_code: io::RawOsError) -> bool { - false -} diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs index 5593e195178de..178f7f506341e 100644 --- a/library/std/src/sys/pal/uefi/os.rs +++ b/library/std/src/sys/pal/uefi/os.rs @@ -9,59 +9,6 @@ use crate::path::{self, PathBuf}; use crate::ptr::NonNull; use crate::{fmt, io}; -pub fn errno() -> io::RawOsError { - 0 -} - -pub fn error_string(errno: io::RawOsError) -> String { - // Keep the List in Alphabetical Order - // The Messages are taken from UEFI Specification Appendix D - Status Codes - #[rustfmt::skip] - let msg = match r_efi::efi::Status::from_usize(errno) { - Status::ABORTED => "The operation was aborted.", - Status::ACCESS_DENIED => "Access was denied.", - Status::ALREADY_STARTED => "The protocol has already been started.", - Status::BAD_BUFFER_SIZE => "The buffer was not the proper size for the request.", - Status::BUFFER_TOO_SMALL => "The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs.", - Status::COMPROMISED_DATA => "The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status.", - Status::CONNECTION_FIN => "The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance.", - Status::CONNECTION_REFUSED => "The receiving or transmission operation fails because this connection is refused.", - Status::CONNECTION_RESET => "The connect fails because the connection is reset either by instance itself or the communication peer.", - Status::CRC_ERROR => "A CRC error was detected.", - Status::DEVICE_ERROR => "The physical device reported an error while attempting the operation.", - Status::END_OF_FILE => "The end of the file was reached.", - Status::END_OF_MEDIA => "Beginning or end of media was reached", - Status::HOST_UNREACHABLE => "The remote host is not reachable.", - Status::HTTP_ERROR => "A HTTP error occurred during the network operation.", - Status::ICMP_ERROR => "An ICMP error occurred during the network operation.", - Status::INCOMPATIBLE_VERSION => "The function encountered an internal version that was incompatible with a version requested by the caller.", - Status::INVALID_LANGUAGE => "The language specified was invalid.", - Status::INVALID_PARAMETER => "A parameter was incorrect.", - Status::IP_ADDRESS_CONFLICT => "There is an address conflict address allocation", - Status::LOAD_ERROR => "The image failed to load.", - Status::MEDIA_CHANGED => "The medium in the device has changed since the last access.", - Status::NETWORK_UNREACHABLE => "The network containing the remote host is not reachable.", - Status::NO_MAPPING => "A mapping to a device does not exist.", - Status::NO_MEDIA => "The device does not contain any medium to perform the operation.", - Status::NO_RESPONSE => "The server was not found or did not respond to the request.", - Status::NOT_FOUND => "The item was not found.", - Status::NOT_READY => "There is no data pending upon return.", - Status::NOT_STARTED => "The protocol has not been started.", - Status::OUT_OF_RESOURCES => "A resource has run out.", - Status::PROTOCOL_ERROR => "A protocol error occurred during the network operation.", - Status::PROTOCOL_UNREACHABLE => "An ICMP protocol unreachable error is received.", - Status::SECURITY_VIOLATION => "The function was not performed due to a security violation.", - Status::TFTP_ERROR => "A TFTP error occurred during the network operation.", - Status::TIMEOUT => "The timeout time expired.", - Status::UNSUPPORTED => "The operation is not supported.", - Status::VOLUME_FULL => "There is no more space on the file system.", - Status::VOLUME_CORRUPTED => "An inconstancy was detected on the file system causing the operating to fail.", - Status::WRITE_PROTECTED => "The device cannot be written to.", - _ => return format!("Status: {errno}"), - }; - msg.to_owned() -} - pub fn getcwd() -> io::Result { match helpers::open_shell() { Some(shell) => { diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs index 265067d84d502..2948d3d594eaa 100644 --- a/library/std/src/sys/pal/unix/futex.rs +++ b/library/std/src/sys/pal/unix/futex.rs @@ -86,7 +86,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) } }; - match (r < 0).then(super::os::errno) { + match (r < 0).then(crate::sys::io::errno) { Some(libc::ETIMEDOUT) => return false, Some(libc::EINTR) => continue, _ => return true, @@ -167,7 +167,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) ) }; - r == 0 || super::os::errno() != libc::ETIMEDOUT + r == 0 || crate::sys::io::errno() != libc::ETIMEDOUT } #[cfg(target_os = "openbsd")] @@ -210,7 +210,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) libc::umtx_sleep(futex as *const Atomic as *const i32, expected as i32, timeout_ms) }; - r == 0 || super::os::errno() != libc::ETIMEDOUT + r == 0 || crate::sys::io::errno() != libc::ETIMEDOUT } // DragonflyBSD doesn't tell us how many threads are woken up, so this always returns false. diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index f24898671af82..6127bb98f80ef 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -91,7 +91,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { target_vendor = "apple", )))] 'poll: { - use crate::sys::os::errno; + use crate::sys::io::errno; let pfds: &mut [_] = &mut [ libc::pollfd { fd: 0, events: 0, revents: 0 }, libc::pollfd { fd: 1, events: 0, revents: 0 }, @@ -135,7 +135,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { target_os = "vita", )))] { - use crate::sys::os::errno; + use crate::sys::io::errno; for fd in 0..3 { if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF { open_devnull(); @@ -224,63 +224,6 @@ pub unsafe fn cleanup() { #[allow(unused_imports)] pub use libc::signal; -#[inline] -pub(crate) fn is_interrupted(errno: i32) -> bool { - errno == libc::EINTR -} - -pub fn decode_error_kind(errno: i32) -> io::ErrorKind { - use io::ErrorKind::*; - match errno as libc::c_int { - libc::E2BIG => ArgumentListTooLong, - libc::EADDRINUSE => AddrInUse, - libc::EADDRNOTAVAIL => AddrNotAvailable, - libc::EBUSY => ResourceBusy, - libc::ECONNABORTED => ConnectionAborted, - libc::ECONNREFUSED => ConnectionRefused, - libc::ECONNRESET => ConnectionReset, - libc::EDEADLK => Deadlock, - libc::EDQUOT => QuotaExceeded, - libc::EEXIST => AlreadyExists, - libc::EFBIG => FileTooLarge, - libc::EHOSTUNREACH => HostUnreachable, - libc::EINTR => Interrupted, - libc::EINVAL => InvalidInput, - libc::EISDIR => IsADirectory, - libc::ELOOP => FilesystemLoop, - libc::ENOENT => NotFound, - libc::ENOMEM => OutOfMemory, - libc::ENOSPC => StorageFull, - libc::ENOSYS => Unsupported, - libc::EMLINK => TooManyLinks, - libc::ENAMETOOLONG => InvalidFilename, - libc::ENETDOWN => NetworkDown, - libc::ENETUNREACH => NetworkUnreachable, - libc::ENOTCONN => NotConnected, - libc::ENOTDIR => NotADirectory, - #[cfg(not(target_os = "aix"))] - libc::ENOTEMPTY => DirectoryNotEmpty, - libc::EPIPE => BrokenPipe, - libc::EROFS => ReadOnlyFilesystem, - libc::ESPIPE => NotSeekable, - libc::ESTALE => StaleNetworkFileHandle, - libc::ETIMEDOUT => TimedOut, - libc::ETXTBSY => ExecutableFileBusy, - libc::EXDEV => CrossesDevices, - libc::EINPROGRESS => InProgress, - libc::EOPNOTSUPP => Unsupported, - - libc::EACCES | libc::EPERM => PermissionDenied, - - // These two constants can have the same value on some systems, - // but different values on others, so we can't use a match - // clause - x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock, - - _ => Uncategorized, - } -} - #[doc(hidden)] pub trait IsMinusOne { fn is_minus_one(&self) -> bool; diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index ef3b4a02f8ae4..b8280a8f29a02 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -14,135 +14,8 @@ use crate::sys::cvt; use crate::sys::helpers::run_path_with_cstr; use crate::{fmt, io, iter, mem, ptr, slice, str}; -const TMPBUF_SZ: usize = 128; - const PATH_SEPARATOR: u8 = b':'; -unsafe extern "C" { - #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))] - #[cfg_attr( - any( - target_os = "linux", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "l4re", - target_os = "hurd", - ), - link_name = "__errno_location" - )] - #[cfg_attr( - any( - target_os = "netbsd", - target_os = "openbsd", - target_os = "cygwin", - target_os = "android", - target_os = "redox", - target_os = "nuttx", - target_env = "newlib" - ), - link_name = "__errno" - )] - #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")] - #[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")] - #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")] - #[cfg_attr(target_os = "haiku", link_name = "_errnop")] - #[cfg_attr(target_os = "aix", link_name = "_Errno")] - // SAFETY: this will always return the same pointer on a given thread. - #[unsafe(ffi_const)] - pub safe fn errno_location() -> *mut c_int; -} - -/// Returns the platform-specific value of errno -#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))] -#[inline] -pub fn errno() -> i32 { - unsafe { (*errno_location()) as i32 } -} - -/// Sets the platform-specific value of errno -// needed for readdir and syscall! -#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))] -#[allow(dead_code)] // but not all target cfgs actually end up using it -#[inline] -pub fn set_errno(e: i32) { - unsafe { *errno_location() = e as c_int } -} - -#[cfg(target_os = "vxworks")] -#[inline] -pub fn errno() -> i32 { - unsafe { libc::errnoGet() } -} - -#[cfg(target_os = "rtems")] -#[inline] -pub fn errno() -> i32 { - unsafe extern "C" { - #[thread_local] - static _tls_errno: c_int; - } - - unsafe { _tls_errno as i32 } -} - -#[cfg(target_os = "dragonfly")] -#[inline] -pub fn errno() -> i32 { - unsafe extern "C" { - #[thread_local] - static errno: c_int; - } - - unsafe { errno as i32 } -} - -#[cfg(target_os = "dragonfly")] -#[allow(dead_code)] -#[inline] -pub fn set_errno(e: i32) { - unsafe extern "C" { - #[thread_local] - static mut errno: c_int; - } - - unsafe { - errno = e; - } -} - -/// Gets a detailed string description for the given error number. -pub fn error_string(errno: i32) -> String { - unsafe extern "C" { - #[cfg_attr( - all( - any( - target_os = "linux", - target_os = "hurd", - target_env = "newlib", - target_os = "cygwin" - ), - not(target_env = "ohos") - ), - link_name = "__xpg_strerror_r" - )] - fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int; - } - - let mut buf = [0 as c_char; TMPBUF_SZ]; - - let p = buf.as_mut_ptr(); - unsafe { - if strerror_r(errno as c_int, p, buf.len()) < 0 { - panic!("strerror_r failure"); - } - - let p = p as *const _; - // We can't always expect a UTF-8 environment. When we don't get that luxury, - // it's better to give a low-quality error message than none at all. - String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into() - } -} - #[cfg(target_os = "espidf")] pub fn getcwd() -> io::Result { Ok(PathBuf::from("/")) diff --git a/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs b/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs index 42eb0cd9a61af..45e2f09f303cd 100644 --- a/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs +++ b/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs @@ -29,7 +29,7 @@ use crate::hint::spin_loop; use crate::ops::Range; use crate::sync::Mutex; use crate::sync::atomic::{AtomicUsize, Ordering}; -use crate::sys::os::errno_location; +use crate::sys::io::errno_location; pub struct ThreadInfo { pub tid: u64, diff --git a/library/std/src/sys/pal/unsupported/common.rs b/library/std/src/sys/pal/unsupported/common.rs index 34a766683830d..d94b9015d0f5f 100644 --- a/library/std/src/sys/pal/unsupported/common.rs +++ b/library/std/src/sys/pal/unsupported/common.rs @@ -16,14 +16,6 @@ pub fn unsupported_err() -> std_io::Error { std_io::Error::UNSUPPORTED_PLATFORM } -pub fn is_interrupted(_code: i32) -> bool { - false -} - -pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { - crate::io::ErrorKind::Uncategorized -} - pub fn abort_internal() -> ! { core::intrinsics::abort(); } diff --git a/library/std/src/sys/pal/unsupported/os.rs b/library/std/src/sys/pal/unsupported/os.rs index 13d2a2044f48a..cb925ef4348db 100644 --- a/library/std/src/sys/pal/unsupported/os.rs +++ b/library/std/src/sys/pal/unsupported/os.rs @@ -4,14 +4,6 @@ use crate::marker::PhantomData; use crate::path::{self, PathBuf}; use crate::{fmt, io}; -pub fn errno() -> i32 { - 0 -} - -pub fn error_string(_errno: i32) -> String { - "operation successful".to_string() -} - pub fn getcwd() -> io::Result { unsupported() } diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 049b435905d43..0abfc2fd79865 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -5,9 +5,7 @@ pub mod time; #[path = "../unsupported/common.rs"] mod unsupported_common; -pub use unsupported_common::{ - decode_error_kind, init, is_interrupted, unsupported, unsupported_err, -}; +pub use unsupported_common::{init, unsupported, unsupported_err}; use crate::arch::global_asm; use crate::ptr; diff --git a/library/std/src/sys/pal/vexos/os.rs b/library/std/src/sys/pal/vexos/os.rs index 405f7c918f4a5..303b452a078ff 100644 --- a/library/std/src/sys/pal/vexos/os.rs +++ b/library/std/src/sys/pal/vexos/os.rs @@ -2,8 +2,8 @@ #[path = "../unsupported/os.rs"] mod unsupported_os; pub use unsupported_os::{ - JoinPathsError, SplitPaths, chdir, current_exe, errno, error_string, getcwd, getpid, home_dir, - join_paths, split_paths, temp_dir, + JoinPathsError, SplitPaths, chdir, current_exe, getcwd, getpid, home_dir, join_paths, + split_paths, temp_dir, }; pub use super::unsupported; diff --git a/library/std/src/sys/pal/wasi/helpers.rs b/library/std/src/sys/pal/wasi/helpers.rs index 6bc41d469584d..4f2eb1148f0b3 100644 --- a/library/std/src/sys/pal/wasi/helpers.rs +++ b/library/std/src/sys/pal/wasi/helpers.rs @@ -1,63 +1,11 @@ #![forbid(unsafe_op_in_unsafe_fn)] -use crate::io as std_io; - -#[inline] -pub fn is_interrupted(errno: i32) -> bool { - errno == libc::EINTR -} - -pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { - use std_io::ErrorKind::*; - match errno as libc::c_int { - libc::E2BIG => ArgumentListTooLong, - libc::EADDRINUSE => AddrInUse, - libc::EADDRNOTAVAIL => AddrNotAvailable, - libc::EBUSY => ResourceBusy, - libc::ECONNABORTED => ConnectionAborted, - libc::ECONNREFUSED => ConnectionRefused, - libc::ECONNRESET => ConnectionReset, - libc::EDEADLK => Deadlock, - libc::EDQUOT => QuotaExceeded, - libc::EEXIST => AlreadyExists, - libc::EFBIG => FileTooLarge, - libc::EHOSTUNREACH => HostUnreachable, - libc::EINTR => Interrupted, - libc::EINVAL => InvalidInput, - libc::EISDIR => IsADirectory, - libc::ELOOP => FilesystemLoop, - libc::ENOENT => NotFound, - libc::ENOMEM => OutOfMemory, - libc::ENOSPC => StorageFull, - libc::ENOSYS => Unsupported, - libc::EMLINK => TooManyLinks, - libc::ENAMETOOLONG => InvalidFilename, - libc::ENETDOWN => NetworkDown, - libc::ENETUNREACH => NetworkUnreachable, - libc::ENOTCONN => NotConnected, - libc::ENOTDIR => NotADirectory, - libc::EPIPE => BrokenPipe, - libc::EROFS => ReadOnlyFilesystem, - libc::ESPIPE => NotSeekable, - libc::ESTALE => StaleNetworkFileHandle, - libc::ETIMEDOUT => TimedOut, - libc::ETXTBSY => ExecutableFileBusy, - libc::EXDEV => CrossesDevices, - libc::EINPROGRESS => InProgress, - libc::EOPNOTSUPP => Unsupported, - libc::EACCES | libc::EPERM => PermissionDenied, - libc::EWOULDBLOCK => WouldBlock, - - _ => Uncategorized, - } -} - pub fn abort_internal() -> ! { unsafe { libc::abort() } } #[inline] #[cfg(target_env = "p1")] -pub(crate) fn err2io(err: wasi::Errno) -> std_io::Error { - std_io::Error::from_raw_os_error(err.raw().into()) +pub(crate) fn err2io(err: wasi::Errno) -> crate::io::Error { + crate::io::Error::from_raw_os_error(err.raw().into()) } diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index 5d36687df0977..9b49db9af6b05 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -26,9 +26,9 @@ mod helpers; // import conflict rules. If we glob export `helpers` and `common` together, // then the compiler complains about conflicts. +pub(crate) use helpers::abort_internal; #[cfg(target_env = "p1")] pub(crate) use helpers::err2io; -pub(crate) use helpers::{abort_internal, decode_error_kind, is_interrupted}; #[cfg(not(target_env = "p1"))] pub use os::IsMinusOne; pub use os::{cvt, cvt_r}; diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs index fee187a8adf3c..285be3ca9fda4 100644 --- a/library/std/src/sys/pal/wasi/os.rs +++ b/library/std/src/sys/pal/wasi/os.rs @@ -6,7 +6,7 @@ use crate::os::wasi::prelude::*; use crate::path::{self, PathBuf}; use crate::sys::helpers::run_path_with_cstr; use crate::sys::unsupported; -use crate::{fmt, io, str}; +use crate::{fmt, io}; // Add a few symbols not in upstream `libc` just yet. pub mod libc { @@ -19,34 +19,6 @@ pub mod libc { } } -unsafe extern "C" { - #[thread_local] - #[link_name = "errno"] - static mut libc_errno: libc::c_int; -} - -pub fn errno() -> i32 { - unsafe { libc_errno as i32 } -} - -pub fn set_errno(val: i32) { - unsafe { - libc_errno = val; - } -} - -pub fn error_string(errno: i32) -> String { - let mut buf = [0 as libc::c_char; 1024]; - - let p = buf.as_mut_ptr(); - unsafe { - if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 { - panic!("strerror_r failure"); - } - str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned() - } -} - pub fn getcwd() -> io::Result { let mut buf = Vec::with_capacity(512); loop { diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 19f0259b1bf09..17e3cdbecd5c2 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -60,84 +60,6 @@ pub unsafe fn cleanup() { winsock::cleanup(); } -#[inline] -pub fn is_interrupted(_errno: i32) -> bool { - false -} - -pub fn decode_error_kind(errno: i32) -> io::ErrorKind { - use io::ErrorKind::*; - - match errno as u32 { - c::ERROR_ACCESS_DENIED => return PermissionDenied, - c::ERROR_ALREADY_EXISTS => return AlreadyExists, - c::ERROR_FILE_EXISTS => return AlreadyExists, - c::ERROR_BROKEN_PIPE => return BrokenPipe, - c::ERROR_FILE_NOT_FOUND - | c::ERROR_PATH_NOT_FOUND - | c::ERROR_INVALID_DRIVE - | c::ERROR_BAD_NETPATH - | c::ERROR_BAD_NET_NAME => return NotFound, - c::ERROR_NO_DATA => return BrokenPipe, - c::ERROR_INVALID_NAME | c::ERROR_BAD_PATHNAME => return InvalidFilename, - c::ERROR_INVALID_PARAMETER => return InvalidInput, - c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory, - c::ERROR_SEM_TIMEOUT - | c::WAIT_TIMEOUT - | c::ERROR_DRIVER_CANCEL_TIMEOUT - | c::ERROR_OPERATION_ABORTED - | c::ERROR_SERVICE_REQUEST_TIMEOUT - | c::ERROR_COUNTER_TIMEOUT - | c::ERROR_TIMEOUT - | c::ERROR_RESOURCE_CALL_TIMED_OUT - | c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT - | c::ERROR_CTX_CLIENT_QUERY_TIMEOUT - | c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT - | c::ERROR_DS_TIMELIMIT_EXCEEDED - | c::DNS_ERROR_RECORD_TIMED_OUT - | c::ERROR_IPSEC_IKE_TIMED_OUT - | c::ERROR_RUNLEVEL_SWITCH_TIMEOUT - | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return TimedOut, - c::ERROR_CALL_NOT_IMPLEMENTED => return Unsupported, - c::ERROR_HOST_UNREACHABLE => return HostUnreachable, - c::ERROR_NETWORK_UNREACHABLE => return NetworkUnreachable, - c::ERROR_DIRECTORY => return NotADirectory, - c::ERROR_DIRECTORY_NOT_SUPPORTED => return IsADirectory, - c::ERROR_DIR_NOT_EMPTY => return DirectoryNotEmpty, - c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem, - c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull, - c::ERROR_SEEK_ON_DEVICE => return NotSeekable, - c::ERROR_DISK_QUOTA_EXCEEDED => return QuotaExceeded, - c::ERROR_FILE_TOO_LARGE => return FileTooLarge, - c::ERROR_BUSY => return ResourceBusy, - c::ERROR_POSSIBLE_DEADLOCK => return Deadlock, - c::ERROR_NOT_SAME_DEVICE => return CrossesDevices, - c::ERROR_TOO_MANY_LINKS => return TooManyLinks, - c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename, - c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop, - _ => {} - } - - match errno { - c::WSAEACCES => PermissionDenied, - c::WSAEADDRINUSE => AddrInUse, - c::WSAEADDRNOTAVAIL => AddrNotAvailable, - c::WSAECONNABORTED => ConnectionAborted, - c::WSAECONNREFUSED => ConnectionRefused, - c::WSAECONNRESET => ConnectionReset, - c::WSAEINVAL => InvalidInput, - c::WSAENOTCONN => NotConnected, - c::WSAEWOULDBLOCK => WouldBlock, - c::WSAETIMEDOUT => TimedOut, - c::WSAEHOSTUNREACH => HostUnreachable, - c::WSAENETDOWN => NetworkDown, - c::WSAENETUNREACH => NetworkUnreachable, - c::WSAEDQUOT => QuotaExceeded, - - _ => Uncategorized, - } -} - pub fn unrolled_find_u16s(needle: u16, haystack: &[u16]) -> Option { let ptr = haystack.as_ptr(); let mut start = haystack; diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs index 1b3c80c079bef..3eb6ec8278401 100644 --- a/library/std/src/sys/pal/windows/os.rs +++ b/library/std/src/sys/pal/windows/os.rs @@ -15,66 +15,6 @@ use crate::path::{self, PathBuf}; use crate::sys::pal::{c, cvt}; use crate::{fmt, io, ptr}; -pub fn errno() -> i32 { - api::get_last_error().code as i32 -} - -/// Gets a detailed string description for the given error number. -pub fn error_string(mut errnum: i32) -> String { - let mut buf = [0 as c::WCHAR; 2048]; - - unsafe { - let mut module = ptr::null_mut(); - let mut flags = 0; - - // NTSTATUS errors may be encoded as HRESULT, which may returned from - // GetLastError. For more information about Windows error codes, see - // `[MS-ERREF]`: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548a - if (errnum & c::FACILITY_NT_BIT as i32) != 0 { - // format according to https://support.microsoft.com/en-us/help/259693 - const NTDLL_DLL: &[u16] = &[ - 'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _, - 'L' as _, 0, - ]; - module = c::GetModuleHandleW(NTDLL_DLL.as_ptr()); - - if !module.is_null() { - errnum ^= c::FACILITY_NT_BIT as i32; - flags = c::FORMAT_MESSAGE_FROM_HMODULE; - } - } - - let res = c::FormatMessageW( - flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS, - module, - errnum as u32, - 0, - buf.as_mut_ptr(), - buf.len() as u32, - ptr::null(), - ) as usize; - if res == 0 { - // Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId, - let fm_err = errno(); - return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})"); - } - - match String::from_utf16(&buf[..res]) { - Ok(mut msg) => { - // Trim trailing CRLF inserted by FormatMessageW - let len = msg.trim_end().len(); - msg.truncate(len); - msg - } - Err(..) => format!( - "OS Error {} (FormatMessageW() returned \ - invalid UTF-16)", - errnum - ), - } - } -} - pub struct SplitPaths<'a> { data: EncodeWide<'a>, must_yield: bool, diff --git a/library/std/src/sys/pal/xous/os.rs b/library/std/src/sys/pal/xous/os.rs index 2da711f89dfaf..cd7b7b59d1127 100644 --- a/library/std/src/sys/pal/xous/os.rs +++ b/library/std/src/sys/pal/xous/os.rs @@ -1,7 +1,6 @@ use super::unsupported; use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; -use crate::os::xous::ffi::Error as XousError; use crate::path::{self, PathBuf}; use crate::sync::atomic::{Atomic, AtomicPtr, Ordering}; use crate::{fmt, io}; @@ -63,14 +62,6 @@ mod c_compat { } } -pub fn errno() -> i32 { - 0 -} - -pub fn error_string(errno: i32) -> String { - Into::::into(errno).to_string() -} - pub fn getcwd() -> io::Result { unsupported() } diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 6dece1055a089..f09020820a031 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -33,14 +33,6 @@ pub fn unsupported_err() -> std_io::Error { std_io::Error::UNSUPPORTED_PLATFORM } -pub fn is_interrupted(_code: i32) -> bool { - false -} - -pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { - crate::io::ErrorKind::Uncategorized -} - pub fn abort_internal() -> ! { core::intrinsics::abort(); } diff --git a/library/std/src/sys/pal/zkvm/os.rs b/library/std/src/sys/pal/zkvm/os.rs index 13d2a2044f48a..cb925ef4348db 100644 --- a/library/std/src/sys/pal/zkvm/os.rs +++ b/library/std/src/sys/pal/zkvm/os.rs @@ -4,14 +4,6 @@ use crate::marker::PhantomData; use crate::path::{self, PathBuf}; use crate::{fmt, io}; -pub fn errno() -> i32 { - 0 -} - -pub fn error_string(_errno: i32) -> String { - "operation successful".to_string() -} - pub fn getcwd() -> io::Result { unsupported() } diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index d627a477dc1ab..31914aeb67c59 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -8,8 +8,8 @@ use crate::num::{NonZero, NonZeroI32}; use crate::path::Path; use crate::process::StdioPipes; use crate::sys::fs::File; +use crate::sys::io::error_string; use crate::sys::pal::helpers; -use crate::sys::pal::os::error_string; use crate::sys::unsupported; use crate::{fmt, io}; diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index 2e1cd7068d7f9..f6bbfed61ef31 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -61,7 +61,7 @@ cfg_select! { let bit = (signum - 1) as usize; if set.is_null() || bit >= (8 * size_of::()) { - crate::sys::pal::os::set_errno(libc::EINVAL); + crate::sys::io::set_errno(libc::EINVAL); return -1; } let raw = slice::from_raw_parts_mut( diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 5ba57e11679cf..53fe69805de31 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -194,7 +194,7 @@ impl Command { // See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html #[cfg(target_os = "nto")] unsafe fn do_fork(&mut self) -> Result { - use crate::sys::os::errno; + use crate::sys::io::errno; let mut delay = MIN_FORKSPAWN_SLEEP; diff --git a/library/std/src/sys/random/linux.rs b/library/std/src/sys/random/linux.rs index 53e2f1da67537..a5b790a1db42c 100644 --- a/library/std/src/sys/random/linux.rs +++ b/library/std/src/sys/random/linux.rs @@ -66,7 +66,7 @@ use crate::os::fd::AsRawFd; use crate::sync::OnceLock; use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; use crate::sync::atomic::{Atomic, AtomicBool}; -use crate::sys::pal::os::errno; +use crate::sys::io::errno; use crate::sys::pal::weak::syscall; fn getrandom(mut bytes: &mut [u8], insecure: bool) { diff --git a/library/std/src/sys/sync/condvar/windows7.rs b/library/std/src/sys/sync/condvar/windows7.rs index f03feef222124..c3f680be4bb5a 100644 --- a/library/std/src/sys/sync/condvar/windows7.rs +++ b/library/std/src/sys/sync/condvar/windows7.rs @@ -1,6 +1,6 @@ use crate::cell::UnsafeCell; +use crate::sys::c; use crate::sys::sync::{Mutex, mutex}; -use crate::sys::{c, os}; use crate::time::Duration; pub struct Condvar { @@ -30,7 +30,7 @@ impl Condvar { 0, ); if r == 0 { - debug_assert_eq!(os::errno() as usize, c::ERROR_TIMEOUT as usize); + debug_assert_eq!(crate::sys::io::errno() as usize, c::ERROR_TIMEOUT as usize); false } else { true diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index d0396ed713009..82e2e0456e649 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -14,10 +14,9 @@ use crate::num::NonZero; use crate::sys::weak::dlsym; #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))] use crate::sys::weak::weak; -use crate::sys::{os, stack_overflow}; use crate::thread::ThreadInit; use crate::time::Duration; -use crate::{cmp, io, ptr}; +use crate::{cmp, io, ptr, sys}; #[cfg(not(any( target_os = "l4re", target_os = "vxworks", @@ -77,7 +76,7 @@ impl Thread { // multiple of the system page size. Because it's definitely // >= PTHREAD_STACK_MIN, it must be an alignment issue. // Round up to the nearest page and try again. - let page_size = os::page_size(); + let page_size = sys::os::page_size(); let stack_size = (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); @@ -114,7 +113,7 @@ impl Thread { // Now that the thread information is set, set up our stack // overflow handler. - let _handler = stack_overflow::Handler::new(); + let _handler = sys::stack_overflow::Handler::new(); rust_start(); } @@ -536,7 +535,7 @@ pub fn sleep(dur: Duration) { secs -= ts.tv_sec as u64; let ts_ptr = &raw mut ts; if libc::nanosleep(ts_ptr, ts_ptr) == -1 { - assert_eq!(os::errno(), libc::EINTR); + assert_eq!(sys::io::errno(), libc::EINTR); secs += ts.tv_sec as u64; nsecs = ts.tv_nsec; } else { diff --git a/tests/ui/stability-attribute/stability-in-private-module.rs b/tests/ui/stability-attribute/stability-in-private-module.rs index df94931690b7c..000de46ab45e3 100644 --- a/tests/ui/stability-attribute/stability-in-private-module.rs +++ b/tests/ui/stability-attribute/stability-in-private-module.rs @@ -1,4 +1,4 @@ fn main() { - let _ = std::sys::os::errno(); + let _ = std::sys::io::errno(); //~^ERROR module `sys` is private } diff --git a/tests/ui/stability-attribute/stability-in-private-module.stderr b/tests/ui/stability-attribute/stability-in-private-module.stderr index e65f8aa9b1fc1..ab27f703ab6bd 100644 --- a/tests/ui/stability-attribute/stability-in-private-module.stderr +++ b/tests/ui/stability-attribute/stability-in-private-module.stderr @@ -1,7 +1,7 @@ error[E0603]: module `sys` is private --> $DIR/stability-in-private-module.rs:2:18 | -LL | let _ = std::sys::os::errno(); +LL | let _ = std::sys::io::errno(); | ^^^ ----- function `errno` is not publicly re-exported | | | private module