@@ -6,13 +6,18 @@ use core::fmt;
6
6
use crate :: bindings;
7
7
use crate :: c_types:: c_int;
8
8
9
+ pub use crate :: bindings:: {
10
+ KERN_ALERT , KERN_CRIT , KERN_DEBUG , KERN_EMERG , KERN_ERR , KERN_INFO , KERN_NOTICE , KERN_WARNING ,
11
+ } ;
12
+
13
+ const LEVEL_LEN : usize = 3 ;
14
+
9
15
#[ doc( hidden) ]
10
- pub fn printk ( s : & [ u8 ] ) {
16
+ pub fn printk ( s : & [ u8 ] , level : & ' static [ u8 ; LEVEL_LEN ] ) {
11
17
// Don't copy the trailing NUL from `KERN_INFO`.
12
- let mut fmt_str = [ 0 ; bindings:: KERN_INFO . len ( ) - 1 + b"%.*s\0 " . len ( ) ] ;
13
- fmt_str[ ..bindings:: KERN_INFO . len ( ) - 1 ]
14
- . copy_from_slice ( & bindings:: KERN_INFO [ ..bindings:: KERN_INFO . len ( ) - 1 ] ) ;
15
- fmt_str[ bindings:: KERN_INFO . len ( ) - 1 ..] . copy_from_slice ( b"%.*s\0 " ) ;
18
+ let mut fmt_str = [ 0 ; LEVEL_LEN - 1 + b"%.*s\0 " . len ( ) ] ;
19
+ fmt_str[ ..LEVEL_LEN - 1 ] . copy_from_slice ( & level[ ..LEVEL_LEN - 1 ] ) ;
20
+ fmt_str[ LEVEL_LEN - 1 ..] . copy_from_slice ( b"%.*s\0 " ) ;
16
21
17
22
// TODO: I believe printk never fails
18
23
unsafe { bindings:: printk ( fmt_str. as_ptr ( ) as _ , s. len ( ) as c_int , s. as_ptr ( ) ) } ;
@@ -52,21 +57,51 @@ impl fmt::Write for LogLineWriter {
52
57
53
58
/// [`println!`] functions the same as it does in `std`, except instead of
54
59
/// printing to `stdout`, it writes to the kernel console at the `KERN_INFO`
55
- /// level.
60
+ /// level. Level can be overwritten with the argument level.
56
61
///
57
62
/// [`println!`]: https://doc.rust-lang.org/stable/std/macro.println.html
58
63
#[ macro_export]
59
64
macro_rules! println {
60
65
( ) => ( {
61
- $crate:: printk:: printk( "\n " . as_bytes( ) ) ;
66
+ println!( level: $crate:: printk:: KERN_INFO ) ;
67
+ } ) ;
68
+ ( level: $level: expr) => ( {
69
+ $crate:: printk:: printk( "\n " . as_bytes( ) , $level) ;
70
+ } ) ;
71
+ ( $msg: expr) => ( {
72
+ println!( level: $crate:: printk:: KERN_INFO , $msg) ;
73
+ } ) ;
74
+ ( level: $level: expr, $msg: expr) => ( {
75
+ $crate:: printk:: printk( concat!( $msg, "\n " ) . as_bytes( ) , $level) ;
76
+ } ) ;
77
+ ( level: $level: expr, $fmt: expr, $( $arg: tt) * ) => ( {
78
+ use :: core:: fmt;
79
+ let mut writer = $crate:: printk:: LogLineWriter :: new( ) ;
80
+ let _ = fmt:: write( & mut writer, format_args!( concat!( $fmt, "\n " ) , $( $arg) * ) ) . unwrap( ) ;
81
+ $crate:: printk:: printk( writer. as_bytes( ) , $crate:: printk:: KERN_INFO ) ;
82
+ } ) ;
83
+ ( $fmt: expr, $( $arg: tt) * ) => ( {
84
+ println!( level: $crate:: printk:: KERN_INFO , $fmt, $( $arg) * ) ;
85
+ } ) ;
86
+ }
87
+
88
+ /// [`eprintln!`] functions the same as it does in `std`, except instead of
89
+ /// printing to `stderr`, it writes to the kernel console at the `KERN_ERR`
90
+ /// level.
91
+ ///
92
+ /// [`eprintln!`]: https://doc.rust-lang.org/stable/std/macro.eprintln.html
93
+ #[ macro_export]
94
+ macro_rules! eprintln {
95
+ ( ) => ( {
96
+ $crate:: printk:: printk( "\n " . as_bytes( ) , $crate:: printk:: KERN_ERR ) ;
62
97
} ) ;
63
98
( $fmt: expr) => ( {
64
- $crate:: printk:: printk( concat!( $fmt, "\n " ) . as_bytes( ) ) ;
99
+ $crate:: printk:: printk( concat!( $fmt, "\n " ) . as_bytes( ) , $crate :: printk :: KERN_ERR ) ;
65
100
} ) ;
66
101
( $fmt: expr, $( $arg: tt) * ) => ( {
67
102
use :: core:: fmt;
68
103
let mut writer = $crate:: printk:: LogLineWriter :: new( ) ;
69
104
let _ = fmt:: write( & mut writer, format_args!( concat!( $fmt, "\n " ) , $( $arg) * ) ) . unwrap( ) ;
70
- $crate:: printk:: printk( writer. as_bytes( ) ) ;
105
+ $crate:: printk:: printk( writer. as_bytes( ) , $crate :: printk :: KERN_ERR ) ;
71
106
} ) ;
72
107
}
0 commit comments