fix: use file locking instead of abstract socket for single instance to avoid rust null byte error
Some checks are pending
Build & Release / Build & test (push) Waiting to run
Build & Release / Build .deb (push) Blocked by required conditions

This commit is contained in:
Khoa Vo 2026-06-29 21:09:48 +07:00
parent 66351de4fd
commit 5242473b93
3 changed files with 35 additions and 14 deletions

View file

@ -504,15 +504,25 @@ fn recover_display_env() {
} }
} }
fn main() -> Result<(), Box<dyn std::error::Error>> { fn ensure_single_instance(name: &str) {
// Ensure single instance to avoid duplicate daemon processes let uid = unsafe { libc::getuid() };
let _listener = match std::os::unix::net::UnixListener::bind("\0vietc-daemon-lock") { let path = format!("/tmp/{}-{}.lock", name, uid);
Ok(l) => l, let path_c = std::ffi::CString::new(path).unwrap();
Err(_) => { let fd = unsafe { libc::open(path_c.as_ptr(), libc::O_CREAT | libc::O_RDWR, 0o600) };
eprintln!("[vietc] Another instance is already running. Exiting."); if fd < 0 {
eprintln!("[{}] Failed to open lock file", name);
std::process::exit(1);
}
let res = unsafe { libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB) };
if res < 0 {
eprintln!("[{}] Another instance is already running. Exiting.", name);
std::process::exit(0); std::process::exit(0);
} }
}; }
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Ensure single instance to avoid duplicate daemon processes
ensure_single_instance("vietc-daemon");
recover_display_env(); recover_display_env();
let config_path = config::find_config_path(); let config_path = config::find_config_path();

View file

@ -14,3 +14,4 @@ toml = "0.8"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
dirs = "5" dirs = "5"
libc = "0.2.186"

View file

@ -179,15 +179,25 @@ fn config_path() -> PathBuf {
.join("vietc") .join("vietc")
} }
fn main() { fn ensure_single_instance(name: &str) {
// Ensure single instance to avoid duplicate tray icons let uid = unsafe { libc::getuid() };
let _listener = match std::os::unix::net::UnixListener::bind("\0vietc-tray-lock") { let path = format!("/tmp/{}-{}.lock", name, uid);
Ok(l) => l, let path_c = std::ffi::CString::new(path).unwrap();
Err(_) => { let fd = unsafe { libc::open(path_c.as_ptr(), libc::O_CREAT | libc::O_RDWR, 0o600) };
eprintln!("[vietc-tray] Another instance is already running. Exiting."); if fd < 0 {
eprintln!("[{}] Failed to open lock file", name);
std::process::exit(1);
}
let res = unsafe { libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB) };
if res < 0 {
eprintln!("[{}] Another instance is already running. Exiting.", name);
std::process::exit(0); std::process::exit(0);
} }
}; }
fn main() {
// Ensure single instance to avoid duplicate tray icons
ensure_single_instance("vietc-tray");
eprintln!("[vietc-tray] Starting"); eprintln!("[vietc-tray] Starting");