Skip to content

Commit b9b1330

Browse files
committed
rust: remove call to bindings::errname when building testlib
This allows us to use, for example, `Result::unwrap` from example code and still be able to compile, link, and run the example. Without this change, an attempt to use `unwrap` in an example results in the following error when making `rusttest`: ``` rust/kernel/error.rs:360: undefined reference to `errname' = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified ``` Signed-off-by: Wedson Almeida Filho <[email protected]>
1 parent fb05dd8 commit b9b1330

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

rust/kernel/error.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -352,23 +352,41 @@ impl Error {
352352
pub fn to_kernel_errno(self) -> c_types::c_int {
353353
self.0
354354
}
355+
356+
/// Returns a string representing the error, if one exists.
357+
#[cfg(not(testlib))]
358+
pub fn name(&self) -> Option<&'static CStr> {
359+
// SAFETY: Just an FFI call, there are no extra safety requirements.
360+
let ptr = unsafe { bindings::errname(-self.0) };
361+
if ptr.is_null() {
362+
None
363+
} else {
364+
// SAFETY: The string returned by `errname` is static and `NUL`-terminated.
365+
Some(unsafe { CStr::from_char_ptr(ptr) })
366+
}
367+
}
368+
369+
/// Returns a string representing the error, if one exists.
370+
///
371+
/// When `testlib` is configured, this always returns `None` to avoid the dependency on a
372+
/// kernel function so that tests that use this (e.g., by calling [`Result::unwrap`]) can still
373+
/// run in userspace.
374+
#[cfg(testlib)]
375+
pub fn name(&self) -> Option<&'static CStr> {
376+
None
377+
}
355378
}
356379

357380
impl fmt::Debug for Error {
358381
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359-
// SAFETY: FFI call.
360-
let name = unsafe { bindings::errname(-self.0) };
361-
362-
if name.is_null() {
382+
match self.name() {
363383
// Print out number if no name can be found.
364-
return f.debug_tuple("Error").field(&-self.0).finish();
384+
None => f.debug_tuple("Error").field(&-self.0).finish(),
385+
// SAFETY: These strings are ASCII-only.
386+
Some(name) => f
387+
.debug_tuple(unsafe { str::from_utf8_unchecked(name) })
388+
.finish(),
365389
}
366-
367-
// SAFETY: `'static` string from C, and is not NULL.
368-
let cstr = unsafe { CStr::from_char_ptr(name) };
369-
// SAFETY: These strings are ASCII-only.
370-
let str = unsafe { str::from_utf8_unchecked(cstr) };
371-
f.debug_tuple(str).finish()
372390
}
373391
}
374392

0 commit comments

Comments
 (0)