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 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<dyn std::error::Error>> {
// 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();

View file

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

View file

@ -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");