From 431f0704813721c80f58e7b196b79891bfb4d4bf Mon Sep 17 00:00:00 2001 From: metent Date: Wed, 6 Mar 2024 22:27:43 +0530 Subject: [PATCH] Add dinit support (#246) * Add dinit support - Add --notify-fd cli flag for ready notifications - Set dinit activation environment when "dinit" feature flag is enabled * Make systemd and dinit environment activation additive * Use NOTIFY_FD env variable instead of --notify-fd cli flag for sending ready notifications * Format with rustfmt --- Cargo.toml | 2 ++ src/main.rs | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 28f6c11..c42ba9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,6 +107,8 @@ systemd = ["dbus"] xdp-gnome-screencast = ["dbus", "pipewire"] # Enables the Tracy profiler instrumentation. profile-with-tracy = ["profiling/profile-with-tracy", "tracy-client/default"] +# Enables dinit integration (global environment) +dinit = [] [profile.release] debug = "line-tables-only" diff --git a/src/main.rs b/src/main.rs index 7f71522..68a9701 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,10 @@ #[macro_use] extern crate tracing; +use std::fmt::Write as _; use std::fs::{self, File}; use std::io::{self, Write}; +use std::os::fd::FromRawFd; use std::path::PathBuf; use std::process::Command; use std::{env, mem}; @@ -211,6 +213,11 @@ fn main() -> Result<(), Box> { warn!("error notifying systemd: {err:?}"); }; + // Send ready notification to specified file descriptor + if let Err(err) = notify_fd() { + warn!("error notifying fd: {err:?}"); + } + // Set up config file watcher. let _watcher = if let Some(path) = path.clone() { let (tx, rx) = calloop::channel::sync_channel(1); @@ -258,16 +265,23 @@ fn import_environment() { ] .join(" "); - #[cfg(feature = "systemd")] - let systemctl = format!("systemctl --user import-environment {variables} && "); - #[cfg(not(feature = "systemd"))] - let systemctl = String::new(); + let mut init_system_import = String::new(); + if cfg!(feature = "systemd") { + write!( + init_system_import, + "systemctl --user import-environment {variables};" + ) + .unwrap(); + } + if cfg!(feature = "dinit") { + write!(init_system_import, "dinitctl setenv {variables};").unwrap(); + } let rv = Command::new("/bin/sh") .args([ "-c", &format!( - "{systemctl}\ + "{init_system_import}\ hash dbus-update-activation-environment 2>/dev/null && \ dbus-update-activation-environment {variables}" ), @@ -302,3 +316,14 @@ fn default_config_path() -> Option { path.push("config.kdl"); Some(path) } + +fn notify_fd() -> anyhow::Result<()> { + let fd = match env::var("NOTIFY_FD") { + Ok(notify_fd) => notify_fd.parse()?, + Err(env::VarError::NotPresent) => return Ok(()), + Err(err) => return Err(err.into()), + }; + let mut notif = unsafe { File::from_raw_fd(fd) }; + notif.write_all(b"READY=1\n")?; + Ok(()) +}