about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2018-05-27T18·09+0200
committerVincent Ambo <mail@tazj.in>2018-05-27T18·09+0200
commitc5cd12b81f3a2908c3f8202dbc94dc535cf092c4 (patch)
tree6e3b0fdf87b198810bc6555c533bcee6c148912e
parent1ed238b4498f6d4f00216021cfa5be89e3cdf209 (diff)
feat(journald): Implement initial libsystemd journal calls
-rw-r--r--.gitignore2
-rw-r--r--src/journald.rs71
-rw-r--r--src/main.rs22
3 files changed, 94 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 70e3cae73de3..29e65519ba35 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
-
+result
 /target
 **/*.rs.bk
diff --git a/src/journald.rs b/src/journald.rs
new file mode 100644
index 000000000000..4892553ea57e
--- /dev/null
+++ b/src/journald.rs
@@ -0,0 +1,71 @@
+//! This module contains FFI-bindings to the journald APi. See
+//! sd-journal(3) for detailed information about the API.
+//!
+//! Only calls required by journaldriver are implemented.
+
+/// This type represents an opaque pointer to an `sd_journal` struct.
+/// It should be changed to an `extern type` once RF1861 is
+/// stabilized.
+enum SdJournal {}
+
+use failure::Error;
+use std::mem;
+
+extern {
+    fn sd_journal_open(sd_journal: *mut SdJournal, flags: usize) -> usize;
+    fn sd_journal_close(sd_journal: *mut SdJournal);
+    fn sd_journal_next(sd_journal: *mut SdJournal) -> usize;
+}
+
+// Safe interface:
+
+/// This struct contains the opaque data used by libsystemd to
+/// reference the journal.
+pub struct Journal {
+    sd_journal: *mut SdJournal,
+}
+
+impl Drop for Journal {
+    fn drop(&mut self) {
+        unsafe {
+            sd_journal_close(self.sd_journal);
+        }
+    }
+}
+
+/// Open the journal for reading. No flags are supplied to libsystemd,
+/// which means that all journal entries will become available.
+pub fn open_journal() -> Result<Journal, Error> {
+    let (mut sd_journal, result) = unsafe {
+        let mut journal: SdJournal = mem::uninitialized();
+        let result = sd_journal_open(&mut journal, 0);
+        (journal, result)
+    };
+
+    ensure!(result == 0, "Could not open journal (errno: {})", result);
+    Ok(Journal { sd_journal: &mut sd_journal })
+}
+
+#[derive(Debug)]
+pub enum NextEntry {
+    /// If no new entries are available in the journal this variant is
+    /// returned.
+    NoEntry,
+
+    Entry,
+}
+
+impl Journal {
+    pub fn read_next(&self) -> Result<NextEntry, Error> {
+        let result = unsafe {
+            sd_journal_next(self.sd_journal)
+        };
+
+        match result {
+            0 => Ok(NextEntry::NoEntry),
+            1 => Ok(NextEntry::Entry),
+            n if n > 1 => bail!("Journal unexpectedly advanced by {} entries!", n),
+            _ => bail!("An error occured while advancing the journal (errno: {})", result),
+        }
+    }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 000000000000..aca6aba900ad
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,22 @@
+#[macro_use] extern crate failure;
+extern crate libc;
+
+mod journald;
+
+use std::process;
+
+fn main() {
+    let mut journal = match journald::open_journal() {
+        Ok(journal) => journal,
+        Err(e) => {
+            println!("{}", e);
+            process::exit(1);
+        },
+    };
+
+    println!("foo");
+    
+    let entry = journal.read_next();
+
+    println!("Entry: {:?}", entry)
+}