@@ -3,7 +3,7 @@ use std::fs::File;
33use std:: io:: Write ;
44use std:: path:: Path ;
55use 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
5675pub 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