Skip to content

Commit d2e3115

Browse files
nbdd0121ojeda
authored andcommitted
rust: error: impl Debug for Error with errname() integration
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 <[email protected]> Signed-off-by: Wedson Almeida Filho <[email protected]> Co-developed-by: Sven Van Asbroeck <[email protected]> Signed-off-by: Sven Van Asbroeck <[email protected]> Signed-off-by: Gary Guo <[email protected]> Signed-off-by: Alice Ryhl <[email protected]> Reviewed-by: Martin Rodriguez Reboredo <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent d09a610 commit d2e3115

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

rust/bindings/bindings_helper.h

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Sorted alphabetically.
77
*/
88

9+
#include <linux/errname.h>
910
#include <linux/slab.h>
1011
#include <linux/refcount.h>
1112
#include <linux/wait.h>

rust/helpers.c

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/bug.h>
2222
#include <linux/build_bug.h>
2323
#include <linux/err.h>
24+
#include <linux/errname.h>
2425
#include <linux/refcount.h>
2526
#include <linux/mutex.h>
2627
#include <linux/spinlock.h>
@@ -110,6 +111,12 @@ long rust_helper_PTR_ERR(__force const void *ptr)
110111
}
111112
EXPORT_SYMBOL_GPL(rust_helper_PTR_ERR);
112113

114+
const char *rust_helper_errname(int err)
115+
{
116+
return errname(err);
117+
}
118+
EXPORT_SYMBOL_GPL(rust_helper_errname);
119+
113120
struct task_struct *rust_helper_get_current(void)
114121
{
115122
return current;

rust/kernel/error.rs

+39
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
//!
55
//! C header: [`include/uapi/asm-generic/errno-base.h`](../../../include/uapi/asm-generic/errno-base.h)
66
7+
use crate::str::CStr;
8+
79
use alloc::{
810
alloc::{AllocError, LayoutError},
911
collections::TryReserveError,
1012
};
1113

1214
use core::convert::From;
15+
use core::fmt;
1316
use core::num::TryFromIntError;
1417
use core::str::Utf8Error;
1518

@@ -133,6 +136,42 @@ impl Error {
133136
// SAFETY: self.0 is a valid error due to its invariant.
134137
unsafe { bindings::ERR_PTR(self.0.into()) as *mut _ }
135138
}
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+
}
136175
}
137176

138177
impl From<AllocError> for Error {

0 commit comments

Comments
 (0)