From 34c1d99a247f7c92ebacd3c9151da960e942a497 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sat, 22 May 2021 06:54:26 +0100 Subject: [PATCH] rust: print out errname in `impl Debug for Error` Signed-off-by: Gary Guo --- rust/kernel/bindings_helper.h | 1 + rust/kernel/error.rs | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/rust/kernel/bindings_helper.h b/rust/kernel/bindings_helper.h index d2cbed8566dea1..0bbaed768abff9 100644 --- a/rust/kernel/bindings_helper.h +++ b/rust/kernel/bindings_helper.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include +#include #include #include #include diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs index 2ffecf30b51d86..c18d29d89c371f 100644 --- a/rust/kernel/error.rs +++ b/rust/kernel/error.rs @@ -4,16 +4,19 @@ //! //! C header: [`include/uapi/asm-generic/errno-base.h`](../../../include/uapi/asm-generic/errno-base.h) +use crate::str::CStr; use crate::{bindings, c_types}; use alloc::{alloc::AllocError, collections::TryReserveError}; use core::convert::From; -use core::{num::TryFromIntError, str::Utf8Error}; +use core::fmt; +use core::num::TryFromIntError; +use core::str::{self, Utf8Error}; /// Generic integer kernel error. /// /// The kernel defines a set of integer generic error codes based on C and /// POSIX ones. These codes may have a more specific meaning in some contexts. -#[derive(Debug)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct Error(c_types::c_int); impl Error { @@ -61,6 +64,27 @@ impl Error { } } +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // SAFETY: FFI call. + #[cfg(CONFIG_SYMBOLIC_ERRNAME)] + let name = unsafe { crate::bindings::errname(-self.0) }; + #[cfg(not(CONFIG_SYMBOLIC_ERRNAME))] + let name: *const c_types::c_char = core::ptr::null(); + + if name.is_null() { + // Print out number if no name can be found. + return f.debug_tuple("Error").field(&-self.0).finish(); + } + + // SAFETY: `'static` string from C, and is not NULL. + let cstr = unsafe { CStr::from_char_ptr(name) }; + // SAFETY: These strings are ASCII-only. + let str = unsafe { str::from_utf8_unchecked(&cstr) }; + f.debug_tuple(str).finish() + } +} + impl From for Error { fn from(_: TryFromIntError) -> Error { Error::EINVAL