diff options
Diffstat (limited to 'getrandom/src/error.rs')
-rw-r--r-- | getrandom/src/error.rs | 178 |
1 files changed, 0 insertions, 178 deletions
diff --git a/getrandom/src/error.rs b/getrandom/src/error.rs deleted file mode 100644 index b2cb9a8..0000000 --- a/getrandom/src/error.rs +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2018 Developers of the Rand project. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -use core::fmt; -use core::num::NonZeroU32; - -/// A small and `no_std` compatible error type. -/// -/// The [`Error::raw_os_error()`] will indicate if the error is from the OS, and -/// if so, which error code the OS gave the application. If such an error is -/// encountered, please consult with your system documentation. -/// -/// Internally this type is a NonZeroU32, with certain values reserved for -/// certain purposes, see [`Error::INTERNAL_START`] and [`Error::CUSTOM_START`]. -#[derive(Copy, Clone, Eq, PartialEq)] -pub struct Error(NonZeroU32); - -impl Error { - #[deprecated(since = "0.1.7")] - /// Unknown error. - pub const UNKNOWN: Error = UNSUPPORTED; - #[deprecated(since = "0.1.7")] - /// System entropy source is unavailable. - pub const UNAVAILABLE: Error = UNSUPPORTED; - - /// Codes below this point represent OS Errors (i.e. positive i32 values). - /// Codes at or above this point, but below [`Error::CUSTOM_START`] are - /// reserved for use by the `rand` and `getrandom` crates. - pub const INTERNAL_START: u32 = 1 << 31; - - /// Codes at or above this point can be used by users to define their own - /// custom errors. - pub const CUSTOM_START: u32 = (1 << 31) + (1 << 30); - - /// Extract the raw OS error code (if this error came from the OS) - /// - /// This method is identical to `std::io::Error::raw_os_error()`, except - /// that it works in `no_std` contexts. If this method returns `None`, the - /// error value can still be formatted via the `Display` implementation. - #[inline] - pub fn raw_os_error(self) -> Option<i32> { - if self.0.get() < Self::INTERNAL_START { - Some(self.0.get() as i32) - } else { - None - } - } - - /// Extract the bare error code. - /// - /// This code can either come from the underlying OS, or be a custom error. - /// Use [`Error::raw_os_error()`] to disambiguate. - #[inline] - pub fn code(self) -> NonZeroU32 { - self.0 - } -} - -cfg_if! { - if #[cfg(unix)] { - fn os_err_desc(errno: i32, buf: &mut [u8]) -> Option<&str> { - let buf_ptr = buf.as_mut_ptr() as *mut libc::c_char; - if unsafe { libc::strerror_r(errno, buf_ptr, buf.len()) } != 0 { - return None; - } - - // Take up to trailing null byte - let n = buf.len(); - let idx = buf.iter().position(|&b| b == 0).unwrap_or(n); - core::str::from_utf8(&buf[..idx]).ok() - } - } else if #[cfg(target_os = "wasi")] { - fn os_err_desc(errno: i32, _buf: &mut [u8]) -> Option<&str> { - core::num::NonZeroU16::new(errno as u16) - .and_then(wasi::wasi_unstable::error_str) - } - } else { - fn os_err_desc(_errno: i32, _buf: &mut [u8]) -> Option<&str> { - None - } - } -} - -impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut dbg = f.debug_struct("Error"); - if let Some(errno) = self.raw_os_error() { - dbg.field("os_error", &errno); - let mut buf = [0u8; 128]; - if let Some(desc) = os_err_desc(errno, &mut buf) { - dbg.field("description", &desc); - } - } else if let Some(desc) = internal_desc(*self) { - dbg.field("internal_code", &self.0.get()); - dbg.field("description", &desc); - } else { - dbg.field("unknown_code", &self.0.get()); - } - dbg.finish() - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(errno) = self.raw_os_error() { - let mut buf = [0u8; 128]; - match os_err_desc(errno, &mut buf) { - Some(desc) => f.write_str(desc), - None => write!(f, "OS Error: {}", errno), - } - } else if let Some(desc) = internal_desc(*self) { - f.write_str(desc) - } else { - write!(f, "Unknown Error: {}", self.0.get()) - } - } -} - -impl From<NonZeroU32> for Error { - fn from(code: NonZeroU32) -> Self { - Self(code) - } -} - -// TODO: Convert to a function when min_version >= 1.33 -macro_rules! internal_error { - ($n:expr) => { - Error(unsafe { NonZeroU32::new_unchecked(Error::INTERNAL_START + $n as u16 as u32) }) - }; -} - -/// Internal Error constants -pub(crate) const UNSUPPORTED: Error = internal_error!(0); -pub(crate) const ERRNO_NOT_POSITIVE: Error = internal_error!(1); -pub(crate) const UNKNOWN_IO_ERROR: Error = internal_error!(2); -pub(crate) const SEC_RANDOM_FAILED: Error = internal_error!(3); -pub(crate) const RTL_GEN_RANDOM_FAILED: Error = internal_error!(4); -pub(crate) const FAILED_RDRAND: Error = internal_error!(5); -pub(crate) const NO_RDRAND: Error = internal_error!(6); -pub(crate) const BINDGEN_CRYPTO_UNDEF: Error = internal_error!(7); -pub(crate) const BINDGEN_GRV_UNDEF: Error = internal_error!(8); -pub(crate) const STDWEB_NO_RNG: Error = internal_error!(9); -pub(crate) const STDWEB_RNG_FAILED: Error = internal_error!(10); -pub(crate) const RAND_SECURE_FATAL: Error = internal_error!(11); - -fn internal_desc(error: Error) -> Option<&'static str> { - match error { - UNSUPPORTED => Some("getrandom: this target is not supported"), - ERRNO_NOT_POSITIVE => Some("errno: did not return a positive value"), - UNKNOWN_IO_ERROR => Some("Unknown std::io::Error"), - SEC_RANDOM_FAILED => Some("SecRandomCopyBytes: call failed"), - RTL_GEN_RANDOM_FAILED => Some("RtlGenRandom: call failed"), - FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"), - NO_RDRAND => Some("RDRAND: instruction not supported"), - BINDGEN_CRYPTO_UNDEF => Some("wasm-bindgen: self.crypto is undefined"), - BINDGEN_GRV_UNDEF => Some("wasm-bindgen: crypto.getRandomValues is undefined"), - STDWEB_NO_RNG => Some("stdweb: no randomness source available"), - STDWEB_RNG_FAILED => Some("stdweb: failed to get randomness"), - RAND_SECURE_FATAL => Some("randSecure: random number generator module is not initialized"), - _ => None, - } -} - -#[cfg(test)] -mod tests { - use super::Error; - use core::mem::size_of; - - #[test] - fn test_size() { - assert_eq!(size_of::<Error>(), 4); - assert_eq!(size_of::<Result<(), Error>>(), 4); - } -} |