about summary refs log tree commit diff
path: root/src/systemd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemd.rs')
-rw-r--r--src/systemd.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/systemd.rs b/src/systemd.rs
new file mode 100644
index 0000000..7bd2142
--- /dev/null
+++ b/src/systemd.rs
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: AGPL-3.0-or-later WITH GPL-3.0-linking-exception
+// SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
+
+use std::io;
+use std::os::raw::{c_char, c_int, c_uint};
+use std::os::unix::prelude::*;
+use std::ptr::null;
+
+extern "C" {
+    fn sd_listen_fds(unset_environment: c_int) -> c_int;
+    fn sd_is_socket_inet(
+        fd: c_int,
+        family: c_int,
+        type_: c_int,
+        listening: c_int,
+        port: u16,
+    ) -> c_int;
+    fn sd_is_socket_unix(
+        fd: c_int,
+        type_: c_int,
+        listening: c_int,
+        path: *const c_char,
+        length: usize,
+    ) -> c_int;
+}
+
+pub fn listen_fds(unset_environment: bool) -> io::Result<c_uint> {
+    let r = unsafe { sd_listen_fds(if unset_environment { 1 } else { 0 }) };
+    if r < 0 {
+        return Err(io::Error::from_raw_os_error(-r));
+    }
+    Ok(r as c_uint)
+}
+
+pub fn is_socket_inet(fd: RawFd) -> io::Result<bool> {
+    let r = unsafe { sd_is_socket_inet(fd, 0, 0, -1, 0) };
+    if r < 0 {
+        return Err(io::Error::from_raw_os_error(-r));
+    }
+    Ok(r != 0)
+}
+
+pub fn is_socket_unix(fd: RawFd) -> io::Result<bool> {
+    let r = unsafe { sd_is_socket_unix(fd, 0, -1, null(), 0) };
+    if r < 0 {
+        return Err(io::Error::from_raw_os_error(-r));
+    }
+    Ok(r != 0)
+}