From 4a2b0b9881f4753d24597eccfe98db65e531d962 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Sat, 14 Sep 2019 00:38:45 +0200 Subject: [PATCH] Add lock file to prevent multiple instances from running. Add status subcommand. Fix #5. Fix #22 --- Cargo.lock | 11 +++++++++++ Cargo.toml | 1 + src/main.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 800cedc..6752f52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -228,6 +228,7 @@ dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", @@ -268,6 +269,15 @@ dependencies = [ "miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -733,6 +743,7 @@ dependencies = [ "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum flate2 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "2adaffba6388640136149e18ed080b77a78611c1e1d6de75aedcdf78df5d4682" +"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" diff --git a/Cargo.toml b/Cargo.toml index 4c772b3..ba7b325 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ regex = "1.3.1" log = "0.4.8" simplelog = "0.7.1" zip = "0.5.3" +fs2 = "0.4.3" [dev-dependencies] tempfile = "3.1.0" diff --git a/src/main.rs b/src/main.rs index 73f09c9..c00b4b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,8 @@ use log::{info, error, LevelFilter}; use simplelog::{CombinedLogger, TermLogger, TerminalMode, SharedLogger}; use std::process::exit; use std::time::Duration; +use std::fs::{File, OpenOptions}; +use fs2::FileExt; mod ui; mod event; @@ -50,6 +52,8 @@ fn main() { .about("Tool to detect current window properties, to simplify filters creation.")) .subcommand(SubCommand::with_name("daemon") .about("Start the daemon without spawning a new process.")) + .subcommand(SubCommand::with_name("status") + .about("Check if the espanso daemon is running or not.")) .get_matches(); @@ -102,9 +106,21 @@ fn main() { daemon_main(config_set); return; } + + if let Some(matches) = matches.subcommand_matches("status") { + status_main(); + return; + } } fn daemon_main(config_set: ConfigSet) { + // Try to acquire lock file + let lock_file = acquire_lock(); + if lock_file.is_none() { + error!("espanso is already running."); + exit(3); + } + info!("starting daemon..."); let (send_channel, receive_channel) = mpsc::channel(); @@ -148,6 +164,17 @@ fn daemon_background(receive_channel: Receiver, config_set: ConfigSet) { event_manager.eventloop(); } +fn status_main() { + let lock_file = acquire_lock(); + if let Some(lock_file) = lock_file { + println!("espanso is not running"); + + release_lock(lock_file); + }else{ + println!("espanso is running"); + } +} + /// Cli tool used to analyze active windows to extract useful information /// to create configuration filters. fn detect_main() { @@ -180,4 +207,27 @@ fn detect_main() { thread::sleep(Duration::from_millis(500)); } +} + +fn acquire_lock() -> Option { + let espanso_dir = context::get_data_dir(); + let lock_file_path = espanso_dir.join("espanso.lock"); + let file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(lock_file_path) + .expect("Cannot create reference to lock file."); + + let res = file.try_lock_exclusive(); + + if let Ok(_) = res { + return Some(file) + } + + None +} + +fn release_lock(lock_file: File) { + lock_file.unlock().unwrap() } \ No newline at end of file