Skip to content

Commit 8c5d59e

Browse files
committed
Rewatch: ignore stale lock for unrelated process name
1 parent 55a50a9 commit 8c5d59e

File tree

1 file changed

+42
-7
lines changed

1 file changed

+42
-7
lines changed

rewatch/src/lock.rs

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::fs::File;
33
use std::io::Write;
44
use std::path::Path;
55
use std::process;
6-
use sysinfo::{PidExt, System, SystemExt};
6+
use sysinfo::{PidExt, ProcessExt, System, SystemExt};
77

88
/* This locking mechanism is meant to never be deleted. Instead, it stores the PID of the process
99
* that's running, when trying to aquire a lock, it checks wether that process is still running. If
@@ -46,11 +46,30 @@ pub enum Lock {
4646
Error(Error),
4747
}
4848

49-
fn pid_exists(to_check_pid: u32) -> bool {
50-
System::new_all()
51-
.processes()
52-
.iter()
53-
.any(|(pid, _process)| pid.as_u32() == to_check_pid)
49+
fn matching_process_name() -> Option<String> {
50+
std::env::current_exe()
51+
.ok()
52+
.and_then(|path| path.file_name().map(|name| name.to_string_lossy().into_owned()))
53+
}
54+
55+
fn pid_matches_current_process(to_check_pid: u32) -> bool {
56+
let system = System::new_all();
57+
let current_process_name = matching_process_name();
58+
59+
system.processes().iter().any(|(pid, process)| {
60+
if pid.as_u32() != to_check_pid {
61+
return false;
62+
}
63+
64+
match &current_process_name {
65+
Some(current_process_name) => process
66+
.exe()
67+
.file_name()
68+
.map(|name| name.to_string_lossy() == current_process_name.as_str())
69+
.unwrap_or_else(|| process.name() == current_process_name.as_str()),
70+
None => true,
71+
}
72+
})
5473
}
5574

5675
pub fn get(folder: &str) -> Lock {
@@ -67,7 +86,9 @@ pub fn get(folder: &str) -> Lock {
6786
// proceed, otherwise we will overwrite the stale lock with our own PID.
6887
match fs::read_to_string(&location) {
6988
Ok(contents) => match contents.parse::<u32>() {
70-
Ok(parsed_pid) if pid_exists(parsed_pid) => return Lock::Error(Error::Locked(parsed_pid)),
89+
Ok(parsed_pid) if pid_matches_current_process(parsed_pid) => {
90+
return Lock::Error(Error::Locked(parsed_pid));
91+
}
7192
Ok(_) => (),
7293
Err(e) => return Lock::Error(Error::ParsingLockfile(e)),
7394
},
@@ -133,4 +154,18 @@ mod tests {
133154
"lockfile should be created"
134155
);
135156
}
157+
158+
#[test]
159+
fn ignores_stale_lock_for_unrelated_process_name() {
160+
let temp_dir = TempDir::new().expect("temp dir should be created");
161+
let project_folder = temp_dir.path().join("project");
162+
let lib_dir = project_folder.join("lib");
163+
fs::create_dir_all(&lib_dir).expect("lib directory should be created");
164+
fs::write(lib_dir.join(LOCKFILE), "1").expect("lockfile should be written");
165+
166+
match get(project_folder.to_str().expect("path should be valid")) {
167+
Lock::Aquired(_) => {}
168+
_ => panic!("expected stale lock from unrelated process to be ignored"),
169+
}
170+
}
136171
}

0 commit comments

Comments
 (0)