@@ -2,6 +2,7 @@ use crate::*;
2
2
use std:: io:: { self , Write } ;
3
3
use std:: os:: raw:: c_char;
4
4
use std:: sync:: atomic:: { AtomicPtr , Ordering } ;
5
+ use std:: fmt;
5
6
6
7
#[ derive( Debug , PartialEq , Eq , PartialOrd , Ord ) ]
7
8
#[ repr( u32 ) ]
@@ -23,16 +24,31 @@ impl From<libbpf_sys::libbpf_print_level> for PrintLevel {
23
24
}
24
25
}
25
26
26
- pub type PrintCallback = fn ( PrintLevel , & str ) ;
27
+ pub type PrintCallback = fn ( PrintLevel , & dyn fmt:: Display ) ;
28
+
29
+ struct Vsprintf {
30
+ fmtstr : * const c_char ,
31
+ va_list : * mut libbpf_sys:: __va_list_tag ,
32
+ }
33
+
34
+ impl fmt:: Display for Vsprintf {
35
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
36
+ let msg = match unsafe { vsprintf:: vsprintf ( self . fmtstr , self . va_list ) } {
37
+ Ok ( s) => s,
38
+ Err ( e) => format ! ( "Failed to parse libbpf output: {}" , e) ,
39
+ } ;
40
+ f. write_str ( & msg)
41
+ }
42
+ }
27
43
28
44
/// Mimic the default print functionality of libbpf. This way if the user calls `set_print` when no
29
45
/// previous callback had been set and then tries to restore it, it will appear to work correctly.
30
- fn default_callback ( lvl : PrintLevel , msg : & str ) {
46
+ fn default_callback ( lvl : PrintLevel , msg : & dyn fmt :: Display ) {
31
47
if lvl == PrintLevel :: Debug {
32
48
return ;
33
49
}
34
50
35
- let _ = io:: stderr ( ) . write ( msg. as_bytes ( ) ) ;
51
+ let _ = io:: stderr ( ) . write ( msg. to_string ( ) . as_bytes ( ) ) ;
36
52
}
37
53
38
54
fn from_ptr ( ptr : * mut ( ) ) -> PrintCallback {
@@ -42,27 +58,15 @@ fn from_ptr(ptr: *mut ()) -> PrintCallback {
42
58
// There is no AtomicFnPtr. This is a workaround.
43
59
static PRINT_CB : AtomicPtr < ( ) > = AtomicPtr :: new ( default_callback as * mut ( ) ) ;
44
60
45
- /// libbpf's default cb uses vfprintf's return code...which is ignored everywhere. Mimic that for
46
- /// completeness
47
61
extern "C" fn outer_print_cb (
48
62
level : libbpf_sys:: libbpf_print_level ,
49
63
fmtstr : * const c_char ,
50
64
va_list : * mut libbpf_sys:: __va_list_tag ,
51
65
) -> i32 {
52
66
let cb = from_ptr ( PRINT_CB . load ( Ordering :: Relaxed ) ) ;
53
- match unsafe { vsprintf:: vsprintf ( fmtstr, va_list) } {
54
- Ok ( s) => {
55
- cb ( level. into ( ) , & s) ;
56
- s. len ( ) as i32
57
- }
58
- Err ( e) => {
59
- cb (
60
- PrintLevel :: Warn ,
61
- & format ! ( "Failed to parse libbpf output: {}" , e) ,
62
- ) ;
63
- -1
64
- }
65
- }
67
+ let msg = Vsprintf { fmtstr, va_list } ;
68
+ cb ( level. into ( ) , & msg) ;
69
+ 1 // return value is ignored by libbpf
66
70
}
67
71
68
72
/// Set a callback to receive log messages from libbpf, instead of printing them to stderr. Returns
0 commit comments