Skip to content

Commit

Permalink
Add helpful comments
Browse files Browse the repository at this point in the history
  • Loading branch information
newtoallofthis123 committed Aug 29, 2024
1 parent dcb6654 commit 0e96057
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
19 changes: 18 additions & 1 deletion swhkd/src/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ struct Args {
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let args = Args::parse();
// we take the default cooldown to the server connection as 650ms
// to make sure that everytime we send a new command, the env is guaranteed to be updated
let default_cooldown: u64 = 650;
env::set_var("RUST_LOG", "swhkd=warn");

Expand All @@ -89,6 +91,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
let invoking_uid = get_uid()?;

log::debug!("Wating for server to start...");
// The first and the most important request for the env
let env = refresh_env(invoking_uid)?.unwrap_or(environ::Env::construct(None));
log::trace!("Environment Aquired");
let log_file_name = if let Some(val) = args.log {
Expand Down Expand Up @@ -128,11 +131,19 @@ async fn main() -> Result<(), Box<dyn Error>> {
let delta = (args.cooldown.unwrap_or(250) as f64 * 0.1) as u64;
let server_cooldown = args.refresh.unwrap_or(default_cooldown - delta);

// Set up a channel to communicate with the server
// The channel can have upto 100 commands in the queue
let (tx, mut rx) = tokio::sync::mpsc::channel::<String>(100);

// We use a arc mutex to make sure that our pairs are valid and also concurrent
// while being used by the threads.
let pairs = Arc::new(Mutex::new(env.pairs.clone()));
let pairs_clone = Arc::clone(&pairs);
let log = log_path.clone();

// We spawn a new thread in the user space to act as the execution thread
// This again has a thread for running the env refresh module when a change is detected from
// the server.
tokio::spawn(async move {
tokio::spawn(async move {
loop {
Expand All @@ -146,14 +157,17 @@ async fn main() -> Result<(), Box<dyn Error>> {
Err(e) => {
log::error!("Error: {}", e);
_ = Command::new("notify-send").arg(format!("ERROR {}", e)).spawn();
exit(1);
log::warn!("Skipping refresh...");
}
}
}
sleep(Duration::from_millis(server_cooldown)).await;
}
});

// When we do receive a command, we spawn a new thread to execute the command
// This thread is spawned in the user space and is used to execute the command and it
// exits after the command is executed.
while let Some(command) = rx.recv().await {
let pairs = pairs.clone();
let log = log.clone();
Expand Down Expand Up @@ -617,7 +631,9 @@ fn get_file_paths(runtime_dir: &str) -> (String, String) {
(pid_file_path, sock_file_path)
}

/// Refreshes the environment variables from the server
fn refresh_env(invoking_uid: u32) -> Result<Option<environ::Env>, Box<dyn Error>> {
// A simple placeholder for the env that is to be refreshed
let env = environ::Env::construct(None);

let (_pid_path, sock_path) =
Expand All @@ -633,6 +649,7 @@ fn refresh_env(invoking_uid: u32) -> Result<Option<environ::Env>, Box<dyn Error>
for mut socket in listener.incoming().flatten() {
let mut buf = String::new();
socket.read_to_string(&mut buf)?;
// If the server doesn't return any variables, return None
if buf.is_empty() {
return Ok(None);
}
Expand Down
2 changes: 1 addition & 1 deletion swhkd/src/environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ pub struct Env {

impl Env {
fn get_env() -> Result<String, Box<dyn Error>> {
// let shell = Self::get_default_shell()?;
let cmd = Command::new("env").output()?;
let stdout = String::from_utf8(cmd.stdout)?;
Ok(stdout)
Expand All @@ -24,6 +23,7 @@ impl Env {
pairs
}

/// Construct the env from the environment variables
pub fn construct(env: Option<&str>) -> Self {
let env = match env {
Some(env) => env.to_string(),
Expand Down
13 changes: 11 additions & 2 deletions swhks/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::{
};

use clap::Parser;
use nix::unistd::daemon;
//use nix::unistd::daemon;
use std::{
env,
os::unix::fs::PermissionsExt,
Expand All @@ -32,6 +32,8 @@ struct Args {
debug: bool,
}

/// Get the environment variables
/// These would be requested from the default shell to make sure that the environment is up-to-date
fn get_env() -> Result<String, Box<dyn std::error::Error>> {
let shell = std::env::var("SHELL")?;
let cmd = Command::new(shell).arg("-c").arg("env").output()?;
Expand All @@ -57,10 +59,14 @@ fn main() -> std::io::Result<()> {
let (_pid_file_path, sock_file_path) = get_file_paths(&runtime_dir);

log::info!("Started SWHKS placeholder server");
let _ = daemon(true, false);

// Daemonize the process
let _ = nix::unistd::daemon(true, false);

setup_swhks(invoking_uid, PathBuf::from(runtime_dir));
loop {
if let Ok(mut stream) = UnixStream::connect(&sock_file_path) {
// Only if the environment has changed, send it to swhkd, else do nothing.
if prev_hash != calculate_hash(get_env().unwrap()) {
log::debug!("Env changed, sending to swhkd");
let new_env = get_env().unwrap();
Expand All @@ -72,6 +78,9 @@ fn main() -> std::io::Result<()> {
}
}

/// Calculates a simple hash of the string
/// Uses the DefaultHasher from the std::hash module which is not a cryptographically secure hash,
/// however, it is good enough for our use case.
pub fn calculate_hash(t: String) -> u64 {
let mut hasher = DefaultHasher::new();
t.hash(&mut hasher);
Expand Down

0 comments on commit 0e96057

Please sign in to comment.