From c63d7177ba716b860e361528f596572920167d27 Mon Sep 17 00:00:00 2001 From: prplV Date: Thu, 5 Sep 2024 14:55:38 +0300 Subject: [PATCH] added linux signals handling + new aliases --- .cargo/config.toml | 3 +- src/main.rs | 10 ++++++ src/signals.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++ src/utils.rs | 6 +--- 4 files changed, 89 insertions(+), 6 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index e02e0f9..f09e756 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -3,8 +3,9 @@ runner = "riscv64-unknown-elf-gdb -q -x gdb_init" linker = "riscv64-linux-gnu-gcc" [alias] -x86_64 = "build --release" +x86_64 = "build --release --target x86_64-unknown-linux-gnu" riscv64 = "build --release --target riscv64gc-unknown-linux-gnu" +rbuild = "build --release" [build] target = "x86_64-unknown-linux-gnu" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 7376b83..737c3d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ use structs::*; use config::*; use utils::*; use logger::setup_logger; +use signals::set_valid_destructor; #[tokio::main(flavor = "multi_thread")] @@ -57,6 +58,15 @@ async fn main() { }); handler.push(event); } + // destructor addition + handler.push( + tokio::spawn(async move { + if let Err(_) = set_valid_destructor(Arc::new(&processes.processes)).await { + error!("Linux signals handler creation failed. Returning..."); + return; + } + }) + ); for i in handler { i.await.unwrap(); } diff --git a/src/signals.rs b/src/signals.rs index e69de29..ee13053 100644 --- a/src/signals.rs +++ b/src/signals.rs @@ -0,0 +1,76 @@ +use crate::structs::{CustomError, TrackingProcess}; +use std::sync::Arc; +use tokio::io; +use tokio::{ + select, + signal::unix::{signal, Signal, SignalKind}, +}; + +type PendingProcesses<'a> = Arc<&'a Vec>; + +pub async fn set_valid_destructor<'a>(prcs: PendingProcesses<'a>) -> Result<(), CustomError> { + let (mut int, mut term, mut stop) = ( + Sig::new(Signals::Sigint), + Sig::new(Signals::Sigterm), + Sig::new(Signals::Sigstop), + ); + + // todo: select! for handlers and exec destructor + select! { + _ = int.post_processing(prcs.clone()) => {log::info!("Interrupting main thread...")}, + _ = term.post_processing(prcs.clone()) => {log::info!("Terminating main thread...")}, + _ = stop.post_processing(prcs.clone()) => {log::info!("Freezing main thread...")}, + } + std::process::exit(1); +} +enum Signals { + Sigint, + Sigterm, + Sigstop, +} +struct Sig { + signal: Signal, + sig_type: Signals, +} +impl Sig { + fn new(signal_type: Signals) -> Self { + Sig { + signal: signal_type.get_signal().unwrap(), + sig_type: signal_type, + } + } +} +impl std::fmt::Display for Signals { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Signals::Sigint => write!(f, "SIGINT"), + Signals::Sigterm => write!(f, "SIGTERM"), + Signals::Sigstop => write!(f, "SIGSTOP"), + } + } +} +impl Signals { + fn get_signal(&self) -> io::Result { + match self { + Signals::Sigint => signal(SignalKind::interrupt()), + Signals::Sigterm => signal(SignalKind::terminate()), + Signals::Sigstop => signal(SignalKind::quit()), + } + } +} +trait SigPostProcessing<'a> { + async fn post_processing(&mut self, prcs: PendingProcesses<'a>) -> io::Result<()>; +} +impl<'a> SigPostProcessing<'a> for Sig { + async fn post_processing(&mut self, prcs: PendingProcesses<'a>) -> io::Result<()> { + // manipulations ... + if let Some(_) = self.signal.recv().await { + log::info!("Got {}", self.sig_type); + prcs.iter().for_each(|proc| { + log::info!("Terminating {}", &proc.name); + let _ = crate::prcs::terminate_process(&proc.name); + }) + } + Ok(()) + } +} diff --git a/src/utils.rs b/src/utils.rs index 171b957..ee18711 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,13 +1,10 @@ -use std::fs::OpenOptions; use std::sync::Arc; use crate::structs::TrackingProcess; use tokio::sync::mpsc; use inotify::Inotify; use std::process::Command; -use chrono::Local; -use env_logger::Builder; use crate::files::create_watcher; -use log::{error, warn, LevelFilter}; +use log::{error, warn}; use crate::prcs::{ is_active, is_frozen, @@ -19,7 +16,6 @@ use crate::prcs::{ }; use tokio::time::Duration; use tokio::join; -use std::io::Write; use crate::files::file_handler; use crate::services::service_handler;