pub mod protocol;
pub mod shim;
pub mod writer;
use std::path::PathBuf;
use crate::constants;
pub fn socket_path(pid: u32) -> PathBuf {
constants::sessions_dir().join(format!("{pid}.sock"))
}
pub fn list_sessions() -> Vec<(u32, PathBuf)> {
let dir = constants::sessions_dir();
let Ok(entries) = std::fs::read_dir(&dir) else {
return Vec::new();
};
let mut sessions = Vec::new();
for entry in entries.flatten() {
let path = entry.path();
if path.extension().and_then(|e| e.to_str()) != Some("sock") {
continue;
}
let Some(stem) = path.file_stem().and_then(|s| s.to_str()) else {
continue;
};
let Ok(pid) = stem.parse::<u32>() else {
continue;
};
if is_pid_alive(pid) {
sessions.push((pid, path));
}
}
sessions
}
pub fn cleanup_stale_sockets() {
let dir = constants::sessions_dir();
let Ok(entries) = std::fs::read_dir(&dir) else {
return;
};
for entry in entries.flatten() {
let path = entry.path();
if path.extension().and_then(|e| e.to_str()) != Some("sock") {
continue;
}
let Some(stem) = path.file_stem().and_then(|s| s.to_str()) else {
continue;
};
let Ok(pid) = stem.parse::<u32>() else {
let _ = std::fs::remove_file(&path);
continue;
};
if !is_pid_alive(pid) {
tracing::info!(
"removing stale socket for dead PID {pid}: {}",
path.display()
);
let _ = std::fs::remove_file(&path);
}
}
}
pub fn is_pid_alive(pid: u32) -> bool {
let Ok(pid_t) = libc::pid_t::try_from(pid) else {
return false;
};
unsafe { libc::kill(pid_t, 0) == 0 }
}