Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  error.rs

  Sprache: Rust
 

#[cfg(feature = "std")]
extern crate std;

use core::fmt;

// This private alias mirrors `std::io::RawOsError`:
// https://doc.rust-lang.org/std/io/type.RawOsError.html)
cfg_if::cfg_if!(
    if #[cfg(target_os = "uefi")] {
        // See the UEFI spec for more information:
        // https://uefi.org/specs/UEFI/2.10/Apx_D_Status_Codes.html
        type RawOsError = usize;
        type NonZeroRawOsError = core::num::NonZeroUsize;
        const UEFI_ERROR_FLAG: RawOsError = 1 << (RawOsError::BITS - 1);
    } else {
        type RawOsError = i32;
        type NonZeroRawOsError = core::num::NonZeroI32;
    }
);

/// 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.
///
/// *If this crate's `"std"` Cargo feature is enabled*, then:
/// - [`getrandom::Error`][Error] implements
///   [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html)
/// - [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html) implements
///   [`From<getrandom::Error>`](https://doc.rust-lang.org/std/convert/trait.From.html).

// note: on non-UEFI targets OS errors are represented as negative integers,
// while on UEFI targets OS errors have the highest bit set to 1.
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Error(NonZeroRawOsError);

impl Error {
    /// This target/platform is not supported by `getrandom`.
    pub const UNSUPPORTED: Error = Self::new_internal(0);
    /// The platform-specific `errno` returned a non-positive value.
    pub const ERRNO_NOT_POSITIVE: Error = Self::new_internal(1);
    /// Encountered an unexpected situation which should not happen in practice.
    pub const UNEXPECTED: Error = Self::new_internal(2);

    /// Internal errors can be in the range of 2^16..2^17
    const INTERNAL_START: RawOsError = 1 << 16;
    /// Custom errors can be in the range of 2^17..(2^17 + 2^16)
    const CUSTOM_START: RawOsError = 1 << 17;

    /// Creates a new instance of an `Error` from a negative error code.
    #[cfg(not(target_os = "uefi"))]
    #[allow(dead_code)]
    pub(superfn from_neg_error_code(code: RawOsError) -> Self {
        if code < 0 {
            let code = NonZeroRawOsError::new(code).expect("`code` is negative");
            Self(code)
        } else {
            Error::UNEXPECTED
        }
    }

    /// Creates a new instance of an `Error` from an UEFI error code.
    #[cfg(target_os = "uefi")]
    #[allow(dead_code)]
    pub(superfn from_uefi_code(code: RawOsError) -> Self {
        if code & UEFI_ERROR_FLAG != 0 {
            let code = NonZeroRawOsError::new(code).expect("The highest bit of `code` is set to 1");
            Self(code)
        } else {
            Self::UNEXPECTED
        }
    }

    /// Extract the raw OS error code (if this error came from the OS)
    ///
    /// This method is identical to [`std::io::Error::raw_os_error()`][1], except
    /// that it works in `no_std` contexts. On most targets this method returns
    /// `Option<i32>`, but some platforms (e.g. UEFI) may use a different primitive
    /// type like `usize`. Consult with the [`RawOsError`] docs for more information.
    ///
    /// If this method returns `None`, the error value can still be formatted via
    /// the `Display` implementation.
    ///
    /// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.raw_os_error
    /// [`RawOsError`]: https://doc.rust-lang.org/std/io/type.RawOsError.html
    #[inline]
    pub fn raw_os_error(self) -> Option<RawOsError> {
        let code = self.0.get();

        // note: in this method we need to cover only backends which rely on
        // `Error::{from_error_code, from_errno, from_uefi_code}` methods,
        // on all other backends this method always returns `None`.

        #[cfg(target_os = "uefi")]
        {
            if code & UEFI_ERROR_FLAG != 0 {
                Some(code)
            } else {
                None
            }
        }

        #[cfg(not(target_os = "uefi"))]
        {
            // On most targets `std` expects positive error codes while retrieving error strings:
            // - `libc`-based targets use `strerror_r` which expects positive error codes.
            // - Hermit relies on the `hermit-abi` crate, which expects positive error codes:
            //   https://docs.rs/hermit-abi/0.4.0/src/hermit_abi/errno.rs.html#400-532
            // - WASIp1 uses the same conventions as `libc`:
            //   https://github.com/rust-lang/rust/blob/1.85.0/library/std/src/sys/pal/wasi/os.rs#L57-L67
            //
            // The only exception is Solid, `std` expects negative system error codes, see:
            // https://github.com/rust-lang/rust/blob/1.85.0/library/std/src/sys/pal/solid/error.rs#L5-L31
            if code >= 0 {
                None
            } else if cfg!(not(target_os = "solid_asp3")) {
                code.checked_neg()
            } else {
                Some(code)
            }
        }
    }

    /// Creates a new instance of an `Error` from a particular custom error code.
    pub const fn new_custom(n: u16) -> Error {
        // SAFETY: code > 0 as CUSTOM_START > 0 and adding `n` won't overflow `RawOsError`.
        let code = Error::CUSTOM_START + (n as RawOsError);
        Error(unsafe { NonZeroRawOsError::new_unchecked(code) })
    }

    /// Creates a new instance of an `Error` from a particular internal error code.
    pub(crateconst fn new_internal(n: u16) -> Error {
        // SAFETY: code > 0 as INTERNAL_START > 0 and adding `n` won't overflow `RawOsError`.
        let code = Error::INTERNAL_START + (n as RawOsError);
        Error(unsafe { NonZeroRawOsError::new_unchecked(code) })
    }

    fn internal_desc(&self) -> Option<&'static str> {
        let desc = match *self {
            Error::UNSUPPORTED => "getrandom: this target is not supported",
            Error::ERRNO_NOT_POSITIVE => "errno: did not return a positive value",
            Error::UNEXPECTED => "unexpected situation",
            #[cfg(any(
                target_os = "ios",
                target_os = "visionos",
                target_os = "watchos",
                target_os = "tvos",
            ))]
            Error::IOS_RANDOM_GEN => "SecRandomCopyBytes: iOS Security framework failure",
            #[cfg(all(windows, target_vendor = "win7"))]
            Error::WINDOWS_RTL_GEN_RANDOM => "RtlGenRandom: Windows system function failure",
            #[cfg(all(feature = "wasm_js", getrandom_backend = "wasm_js"))]
            Error::WEB_CRYPTO => "Web Crypto API is unavailable",
            #[cfg(target_os = "vxworks")]
            Error::VXWORKS_RAND_SECURE => "randSecure: VxWorks RNG module is not initialized",

            #[cfg(any(
                getrandom_backend = "rdrand",
                all(target_arch = "x86_64", target_env = "sgx")
            ))]
            Error::FAILED_RDRAND => "RDRAND: failed multiple times: CPU issue likely",
            #[cfg(any(
                getrandom_backend = "rdrand",
                all(target_arch = "x86_64", target_env = "sgx")
            ))]
            Error::NO_RDRAND => "RDRAND: instruction not supported",

            #[cfg(getrandom_backend = "rndr")]
            Error::RNDR_FAILURE => "RNDR: Could not generate a random number",
            #[cfg(getrandom_backend = "rndr")]
            Error::RNDR_NOT_AVAILABLE => "RNDR: Register not supported",
            _ => return None,
        };
        Some(desc)
    }
}

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);
            #[cfg(feature = "std")]
            dbg.field("description", &std::io::Error::from_raw_os_error(errno));
        } else if let Some(desc) = self.internal_desc() {
            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() {
            cfg_if! {
                if #[cfg(feature = "std")] {
                    std::io::Error::from_raw_os_error(errno).fmt(f)
                } else {
                    write!(f, "OS Error: {}", errno)
                }
            }
        } else if let Some(desc) = self.internal_desc() {
            f.write_str(desc)
        } else {
            write!(f, "Unknown Error: {}"self.0.get())
        }
    }
}

Messung V0.5 in Prozent
C=76 H=97 G=86

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet am  2026-08-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=434850
#Domains=661743