@@ -352,23 +352,41 @@ impl Error {
352
352
pub fn to_kernel_errno ( self ) -> c_types:: c_int {
353
353
self . 0
354
354
}
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
+ }
355
378
}
356
379
357
380
impl fmt:: Debug for Error {
358
381
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 ( ) {
363
383
// 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 ( ) ,
365
389
}
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 ( )
372
390
}
373
391
}
374
392
0 commit comments