|
4 | 4 | //!
|
5 | 5 | //! C header: [`include/uapi/asm-generic/errno-base.h`](../../../include/uapi/asm-generic/errno-base.h)
|
6 | 6 |
|
| 7 | +use crate::str::CStr; |
| 8 | + |
7 | 9 | use alloc::{
|
8 | 10 | alloc::{AllocError, LayoutError},
|
9 | 11 | collections::TryReserveError,
|
10 | 12 | };
|
11 | 13 |
|
12 | 14 | use core::convert::From;
|
| 15 | +use core::fmt; |
13 | 16 | use core::num::TryFromIntError;
|
14 | 17 | use core::str::Utf8Error;
|
15 | 18 |
|
@@ -133,6 +136,42 @@ impl Error {
|
133 | 136 | // SAFETY: self.0 is a valid error due to its invariant.
|
134 | 137 | unsafe { bindings::ERR_PTR(self.0.into()) as *mut _ }
|
135 | 138 | }
|
| 139 | + |
| 140 | + /// Returns a string representing the error, if one exists. |
| 141 | + #[cfg(not(testlib))] |
| 142 | + pub fn name(&self) -> Option<&'static CStr> { |
| 143 | + // SAFETY: Just an FFI call, there are no extra safety requirements. |
| 144 | + let ptr = unsafe { bindings::errname(-self.0) }; |
| 145 | + if ptr.is_null() { |
| 146 | + None |
| 147 | + } else { |
| 148 | + // SAFETY: The string returned by `errname` is static and `NUL`-terminated. |
| 149 | + Some(unsafe { CStr::from_char_ptr(ptr) }) |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + /// Returns a string representing the error, if one exists. |
| 154 | + /// |
| 155 | + /// When `testlib` is configured, this always returns `None` to avoid the dependency on a |
| 156 | + /// kernel function so that tests that use this (e.g., by calling [`Result::unwrap`]) can still |
| 157 | + /// run in userspace. |
| 158 | + #[cfg(testlib)] |
| 159 | + pub fn name(&self) -> Option<&'static CStr> { |
| 160 | + None |
| 161 | + } |
| 162 | +} |
| 163 | + |
| 164 | +impl fmt::Debug for Error { |
| 165 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 166 | + match self.name() { |
| 167 | + // Print out number if no name can be found. |
| 168 | + None => f.debug_tuple("Error").field(&-self.0).finish(), |
| 169 | + // SAFETY: These strings are ASCII-only. |
| 170 | + Some(name) => f |
| 171 | + .debug_tuple(unsafe { core::str::from_utf8_unchecked(name) }) |
| 172 | + .finish(), |
| 173 | + } |
| 174 | + } |
136 | 175 | }
|
137 | 176 |
|
138 | 177 | impl From<AllocError> for Error {
|
|
0 commit comments