fix: disconnect VPN when sleep/shutdown

This commit is contained in:
Kevin Yue
2025-01-12 14:41:03 +08:00
parent ec85e857bc
commit 9740231910
18 changed files with 285 additions and 172 deletions

View File

@@ -16,7 +16,7 @@ clap.workspace = true
env_logger.workspace = true
inquire = "0.7"
log.workspace = true
tokio.workspace = true
tokio = { workspace = true, features = ["rt-multi-thread"] }
sysinfo.workspace = true
serde_json.workspace = true
whoami.workspace = true

View File

@@ -1,6 +1,7 @@
use crate::GP_CLIENT_LOCK_FILE;
use gpapi::GP_SERVICE_LOCK_FILE;
use log::{info, warn};
use std::fs;
use std::{fs, str::FromStr, thread, time::Duration};
use sysinfo::{Pid, Signal, System};
pub(crate) struct DisconnectHandler;
@@ -11,21 +12,40 @@ impl DisconnectHandler {
}
pub(crate) fn handle(&self) -> anyhow::Result<()> {
if fs::metadata(GP_CLIENT_LOCK_FILE).is_err() {
warn!("PID file not found, maybe the client is not running");
return Ok(());
}
if let Ok(c) = fs::read_to_string(GP_CLIENT_LOCK_FILE) {
send_signal(c.trim(), Signal::Interrupt).unwrap_or_else(|err| {
warn!("Failed to send signal to client: {}", err);
});
};
let pid = fs::read_to_string(GP_CLIENT_LOCK_FILE)?;
let pid = pid.trim().parse::<usize>()?;
let s = System::new_all();
if let Ok(c) = fs::read_to_string(GP_SERVICE_LOCK_FILE) {
c.split(':').next().map_or_else(
|| info!("Failed to extract PID from: {}", c),
|pid| {
send_signal(pid, Signal::User1).unwrap_or_else(|err| {
warn!("Failed to send signal to service: {}", err);
});
},
);
};
// sleep for 3 seconds to give the client and service time to shut down
thread::sleep(Duration::from_secs(3));
if let Some(process) = s.process(Pid::from(pid)) {
info!("Found process {}, killing...", pid);
if process.kill_with(Signal::Interrupt).is_none() {
warn!("Failed to kill process {}", pid);
}
}
Ok(())
}
}
fn send_signal(pid: &str, signal: Signal) -> anyhow::Result<()> {
let s = System::new_all();
let pid = Pid::from_str(pid)?;
if let Some(process) = s.process(pid) {
info!("Found process {}, sending signal...", pid);
if process.kill_with(signal).is_none() {
warn!("Failed to kill process {}", pid);
}
}
Ok(())
}