diff --git a/daemon/src/main.rs b/daemon/src/main.rs index f732485..a64e3ca 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -504,15 +504,25 @@ fn recover_display_env() { } } +fn ensure_single_instance(name: &str) { + let uid = unsafe { libc::getuid() }; + let path = format!("/tmp/{}-{}.lock", name, uid); + let path_c = std::ffi::CString::new(path).unwrap(); + let fd = unsafe { libc::open(path_c.as_ptr(), libc::O_CREAT | libc::O_RDWR, 0o600) }; + 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); + } +} + fn main() -> Result<(), Box> { // Ensure single instance to avoid duplicate daemon processes - let _listener = match std::os::unix::net::UnixListener::bind("\0vietc-daemon-lock") { - Ok(l) => l, - Err(_) => { - eprintln!("[vietc] Another instance is already running. Exiting."); - std::process::exit(0); - } - }; + ensure_single_instance("vietc-daemon"); recover_display_env(); let config_path = config::find_config_path(); diff --git a/ui/Cargo.toml b/ui/Cargo.toml index 08a930b..ce84e0a 100644 --- a/ui/Cargo.toml +++ b/ui/Cargo.toml @@ -14,3 +14,4 @@ toml = "0.8" serde = { version = "1", features = ["derive"] } serde_json = "1.0" dirs = "5" +libc = "0.2.186" diff --git a/ui/src/main.rs b/ui/src/main.rs index 6152764..42ccc42 100644 --- a/ui/src/main.rs +++ b/ui/src/main.rs @@ -179,15 +179,25 @@ fn config_path() -> PathBuf { .join("vietc") } +fn ensure_single_instance(name: &str) { + let uid = unsafe { libc::getuid() }; + let path = format!("/tmp/{}-{}.lock", name, uid); + let path_c = std::ffi::CString::new(path).unwrap(); + let fd = unsafe { libc::open(path_c.as_ptr(), libc::O_CREAT | libc::O_RDWR, 0o600) }; + 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); + } +} + fn main() { // Ensure single instance to avoid duplicate tray icons - let _listener = match std::os::unix::net::UnixListener::bind("\0vietc-tray-lock") { - Ok(l) => l, - Err(_) => { - eprintln!("[vietc-tray] Another instance is already running. Exiting."); - std::process::exit(0); - } - }; + ensure_single_instance("vietc-tray"); eprintln!("[vietc-tray] Starting");