|
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; |
7 | 8 | use crate::{bindings, c_types}; |
8 | 9 | use alloc::{alloc::AllocError, collections::TryReserveError}; |
9 | 10 | use core::convert::From; |
10 | | -use core::{num::TryFromIntError, str::Utf8Error}; |
| 11 | +use core::fmt; |
| 12 | +use core::num::TryFromIntError; |
| 13 | +use core::str::{self, Utf8Error}; |
11 | 14 |
|
12 | 15 | /// Generic integer kernel error. |
13 | 16 | /// |
14 | 17 | /// The kernel defines a set of integer generic error codes based on C and |
15 | 18 | /// POSIX ones. These codes may have a more specific meaning in some contexts. |
16 | | -#[derive(Debug)] |
| 19 | +#[derive(Clone, Copy, PartialEq, Eq)] |
17 | 20 | pub struct Error(c_types::c_int); |
18 | 21 |
|
19 | 22 | impl Error { |
@@ -61,6 +64,27 @@ impl Error { |
61 | 64 | } |
62 | 65 | } |
63 | 66 |
|
| 67 | +impl fmt::Debug for Error { |
| 68 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 69 | + // SAFETY: FFI call. |
| 70 | + #[cfg(CONFIG_SYMBOLIC_ERRNAME)] |
| 71 | + let name = unsafe { crate::bindings::errname(-self.0) }; |
| 72 | + #[cfg(not(CONFIG_SYMBOLIC_ERRNAME))] |
| 73 | + let name: *const c_types::c_char = core::ptr::null(); |
| 74 | + |
| 75 | + if name.is_null() { |
| 76 | + // Print out number if no name can be found. |
| 77 | + return f.debug_tuple("Error").field(&-self.0).finish(); |
| 78 | + } |
| 79 | + |
| 80 | + // SAFETY: `'static` string from C, and is not NULL. |
| 81 | + let cstr = unsafe { CStr::from_char_ptr(name) }; |
| 82 | + // SAFETY: These strings are ASCII-only. |
| 83 | + let str = unsafe { str::from_utf8_unchecked(&cstr) }; |
| 84 | + f.debug_tuple(str).finish() |
| 85 | + } |
| 86 | +} |
| 87 | + |
64 | 88 | impl From<TryFromIntError> for Error { |
65 | 89 | fn from(_: TryFromIntError) -> Error { |
66 | 90 | Error::EINVAL |
|
0 commit comments