xref: /linux/rust/kernel/seq_file.rs (revision 352af6a011d586ff042db4b2d1f7421875eb8a14)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Seq file bindings.
4 //!
5 //! C header: [`include/linux/seq_file.h`](srctree/include/linux/seq_file.h)
6 
7 use crate::{bindings, c_str, types::NotThreadSafe, types::Opaque};
8 
9 /// A utility for generating the contents of a seq file.
10 #[repr(transparent)]
11 pub struct SeqFile {
12     inner: Opaque<bindings::seq_file>,
13     _not_send: NotThreadSafe,
14 }
15 
16 impl SeqFile {
17     /// Creates a new [`SeqFile`] from a raw pointer.
18     ///
19     /// # Safety
20     ///
21     /// The caller must ensure that for the duration of `'a` the following is satisfied:
22     /// * The pointer points at a valid `struct seq_file`.
23     /// * The `struct seq_file` is not accessed from any other thread.
from_raw<'a>(ptr: *mut bindings::seq_file) -> &'a SeqFile24     pub unsafe fn from_raw<'a>(ptr: *mut bindings::seq_file) -> &'a SeqFile {
25         // SAFETY: The caller ensures that the reference is valid for 'a. There's no way to trigger
26         // a data race by using the `&SeqFile` since this is the only thread accessing the seq_file.
27         //
28         // CAST: The layout of `struct seq_file` and `SeqFile` is compatible.
29         unsafe { &*ptr.cast() }
30     }
31 
32     /// Used by the [`seq_print`] macro.
33     #[inline]
call_printf(&self, args: core::fmt::Arguments<'_>)34     pub fn call_printf(&self, args: core::fmt::Arguments<'_>) {
35         // SAFETY: Passing a void pointer to `Arguments` is valid for `%pA`.
36         unsafe {
37             bindings::seq_printf(
38                 self.inner.get(),
39                 c_str!("%pA").as_char_ptr(),
40                 core::ptr::from_ref(&args).cast::<crate::ffi::c_void>(),
41             );
42         }
43     }
44 }
45 
46 /// Write to a [`SeqFile`] with the ordinary Rust formatting syntax.
47 #[macro_export]
48 macro_rules! seq_print {
49     ($m:expr, $($arg:tt)+) => (
50         $m.call_printf(format_args!($($arg)+))
51     );
52 }
53 pub use seq_print;
54