systemd/
lib.rs

1#![cfg_attr(feature = "unstable-doc-cfg", feature(doc_cfg))]
2#![warn(rust_2018_idioms)]
3
4extern crate libsystemd_sys as ffi;
5
6/*
7extern crate enumflags2;
8#[macro_use]
9extern crate enumflags2_derive;
10*/
11
12#[cfg(feature = "journal")]
13#[allow(deprecated)]
14pub use journal::JournalFiles;
15#[cfg(feature = "journal")]
16pub use journal::{Journal, JournalLog, JournalRecord, JournalSeek, JournalWaitResult};
17use libc::{c_char, c_void, free, strlen};
18pub use std::io::{Error, Result};
19
20#[cfg(any(feature = "journal", feature = "bus"))]
21fn usec_from_duration(duration: std::time::Duration) -> u64 {
22    let sub_usecs = duration.subsec_micros() as u64;
23    duration.as_secs() * 1_000_000 + sub_usecs
24}
25
26/// Convert a systemd ffi return value into a Result
27pub fn ffi_result(ret: ffi::c_int) -> Result<ffi::c_int> {
28    if ret < 0 {
29        Err(Error::from_raw_os_error(-ret))
30    } else {
31        Ok(ret)
32    }
33}
34
35/// Convert a malloc'd C string into a rust string and call free on it.
36/// Returns None if the pointer is null.
37unsafe fn free_cstring(ptr: *mut c_char) -> Option<String> {
38    if ptr.is_null() {
39        return None;
40    }
41    let len = strlen(ptr);
42    let char_slice = std::slice::from_raw_parts(ptr as *mut u8, len);
43    let s = String::from_utf8_lossy(char_slice).into_owned();
44    free(ptr as *mut c_void);
45    Some(s)
46}
47
48/// An analogue of `try!()` for systemd FFI calls.
49///
50/// The parameter should be a call to a systemd FFI fn with an c_int return
51/// value. It is called, and if the return is negative then `sd_try!()`
52/// interprets it as an error code and returns IoError from the enclosing fn.
53/// Otherwise, the value of `sd_try!()` is the non-negative value returned by
54/// the FFI call.
55#[macro_export]
56macro_rules! sd_try {
57    ($e:expr) => {{
58        $crate::ffi_result(unsafe { $e })?
59    }};
60}
61
62/// High-level interface to the systemd journal.
63///
64/// The main interface for writing to the journal is `fn log()`, and the main
65/// interface for reading the journal is `struct Journal`.
66#[cfg(feature = "journal")]
67pub mod journal;
68
69/// Similar to `log!()`, except it accepts a func argument rather than hard
70/// coding `::log::log()`, and it doesn't filter on `log_enabled!()`.
71#[macro_export]
72macro_rules! log_with{
73    ($func:expr, $lvl:expr, $($arg:tt),+) => ({
74        $func(&::log::Record::builder()
75            .args(format_args!($($arg),+))
76            .level($lvl)
77            .file(Some(file!()))
78            .line(Some(line!()))
79            .module_path(Some(module_path!()))
80            .build())
81    });
82    (@raw $func:expr, $lvl:expr, $($arg:tt),+) => ({
83        $func($lvl, file!(), line!(), module_path!(), &format_args!($($arg),+))
84    });
85    (@target $tgt:expr, $func:expr, $lvl:expr, $($arg:tt),+) => ({
86        $func(&::log::Record::builder()
87            .args(format_args!($($arg),+))
88            .level($lvl)
89            .target($tgt)
90            .file(Some(file!()))
91            .line(Some(line!()))
92            .module_path(Some(module_path!()))
93            .build())
94    })
95}
96
97#[cfg(feature = "journal")]
98#[macro_export]
99macro_rules! sd_journal_log{
100    ($lvl:expr, $($arg:tt)+) => ($crate::log_with!(@raw ::systemd::journal::log, $lvl, $($arg)+))
101}
102
103pub mod daemon;
104
105pub mod id128;
106
107/// Interface to introspect on seats, sessions and users.
108pub mod login;
109
110/// An interface to work with the dbus message bus.
111///
112#[cfg(feature = "bus")]
113pub mod bus;
114
115/// Utilities for working with systemd units.
116pub mod unit;