diff options
| author | Gary Guo <gary@garyguo.net> | 2023-05-31 17:44:50 +0000 | 
|---|---|---|
| committer | Miguel Ojeda <ojeda@kernel.org> | 2023-06-13 01:24:42 +0200 | 
| commit | d2e3115d717197cb2bc020dd1f06b06538474ac3 (patch) | |
| tree | ce25ae73636780e460a5a3a7f714ec1f3b075f16 /rust/kernel/error.rs | |
| parent | d09a61024f6b78c6a08892fc916cdafd87b50365 (diff) | |
rust: error: `impl Debug` for `Error` with `errname()` integrationrust-6.5
Integrate the `Error` type with `errname()` by providing a new
`name()` method.
Then, implement `Debug` for the type using the new method.
[ Miguel: under `CONFIG_SYMBOLIC_ERRNAME=n`, `errname()` is a
  `static inline`, so added a helper to support that case,
  like we had in the `rust` branch. Also moved `#include` up
  and reworded commit message for clarity. ]
Co-developed-by: Wedson Almeida Filho <walmeida@microsoft.com>
Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Link: https://lore.kernel.org/r/20230531174450.3733220-1-aliceryhl@google.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/kernel/error.rs')
| -rw-r--r-- | rust/kernel/error.rs | 39 | 
1 files changed, 39 insertions, 0 deletions
diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs index 7c1ce2bccd08..05fcab6abfe6 100644 --- a/rust/kernel/error.rs +++ b/rust/kernel/error.rs @@ -4,12 +4,15 @@  //!  //! C header: [`include/uapi/asm-generic/errno-base.h`](../../../include/uapi/asm-generic/errno-base.h) +use crate::str::CStr; +  use alloc::{      alloc::{AllocError, LayoutError},      collections::TryReserveError,  };  use core::convert::From; +use core::fmt;  use core::num::TryFromIntError;  use core::str::Utf8Error; @@ -133,6 +136,42 @@ impl Error {          // SAFETY: self.0 is a valid error due to its invariant.          unsafe { bindings::ERR_PTR(self.0.into()) as *mut _ }      } + +    /// Returns a string representing the error, if one exists. +    #[cfg(not(testlib))] +    pub fn name(&self) -> Option<&'static CStr> { +        // SAFETY: Just an FFI call, there are no extra safety requirements. +        let ptr = unsafe { bindings::errname(-self.0) }; +        if ptr.is_null() { +            None +        } else { +            // SAFETY: The string returned by `errname` is static and `NUL`-terminated. +            Some(unsafe { CStr::from_char_ptr(ptr) }) +        } +    } + +    /// Returns a string representing the error, if one exists. +    /// +    /// When `testlib` is configured, this always returns `None` to avoid the dependency on a +    /// kernel function so that tests that use this (e.g., by calling [`Result::unwrap`]) can still +    /// run in userspace. +    #[cfg(testlib)] +    pub fn name(&self) -> Option<&'static CStr> { +        None +    } +} + +impl fmt::Debug for Error { +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +        match self.name() { +            // Print out number if no name can be found. +            None => f.debug_tuple("Error").field(&-self.0).finish(), +            // SAFETY: These strings are ASCII-only. +            Some(name) => f +                .debug_tuple(unsafe { core::str::from_utf8_unchecked(name) }) +                .finish(), +        } +    }  }  impl From<AllocError> for Error {  | 
