use crate::LOGGER; use crate::backend::{BackendThread, SimpleBackendThread}; use crossbeam_channel::{Receiver, Sender}; use jmb_bar::{ControlCommand, SOCKET_PATH}; use jmb_logger_rs::*; use std::io::Read; use std::net::Shutdown; use std::os::unix::net::UnixListener; use std::str::FromStr; use std::sync::{Arc, Mutex}; pub struct ControlSocket { subscribers: Vec>, } impl ControlSocket { pub fn new() -> Self { Self { subscribers: vec![], } } } impl SimpleBackendThread for ControlSocket { fn subscribers(&self) -> &Vec> { &self.subscribers } fn init(self, registration_rx: Receiver>) { let instance = Arc::new(Mutex::new(self)); let instance_clone = instance.clone(); std::thread::spawn(move || { while let Ok(sender) = registration_rx.recv() { instance_clone.lock().unwrap().subscribers.push(sender); } }); std::thread::spawn(move || { if std::fs::metadata(SOCKET_PATH).is_ok() && let Err(e) = std::fs::remove_file(SOCKET_PATH) { error!(&LOGGER, "Error deleting old socket file: {e}"); return; } let socket = UnixListener::bind(SOCKET_PATH); let Ok(socket) = socket else { error!(&LOGGER, "Error creating socket {}", socket.err().unwrap()); return; }; info!(&LOGGER, "Successfully started control socket"); loop { if let Ok((mut stream, _addr)) = socket.accept() { info!(&LOGGER, "Socket accepted connection"); let mut read = String::new(); let res = stream.read_to_string(&mut read); if let Err(e) = res { error!(&LOGGER, "Error reading: {e}"); let _ = stream.shutdown(Shutdown::Both); continue; } if let Ok(command) = ControlCommand::from_str(&read) { instance.lock().unwrap().publish(command); } } } }); } }