entracte_lib/plugins/
detect.rs1use std::path::Path;
11
12use sysinfo::{ProcessesToUpdate, System};
13
14use crate::proc_match::process_match_lower;
15
16pub fn process_running(pattern: &str) -> bool {
22 let target = pattern.trim().to_lowercase();
23 if target.is_empty() {
24 return false;
25 }
26 let mut sys = System::new();
27 sys.refresh_processes(ProcessesToUpdate::All, false);
28 sys.processes().values().any(|p| {
29 let name = p.name().to_string_lossy().to_lowercase();
30 process_match_lower(&name, &target)
31 })
32}
33
34const MAX_FLAG_BYTES: u64 = 64 * 1024;
37
38pub fn flag_is_truthy(contents: &str) -> bool {
41 matches!(
42 contents.trim().to_lowercase().as_str(),
43 "1" | "true" | "yes" | "on"
44 )
45}
46
47pub fn read_flag(path: &Path) -> bool {
51 crate::secure_io::read_capped(path, MAX_FLAG_BYTES)
52 .map(|contents| flag_is_truthy(&contents))
53 .unwrap_or(false)
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn flag_truthy_accepts_known_tokens_only() {
62 for t in ["1", "true", "TRUE", " yes ", "On\n"] {
63 assert!(flag_is_truthy(t), "{t:?} should be truthy");
64 }
65 for f in ["0", "false", "", "maybe", "2"] {
66 assert!(!flag_is_truthy(f), "{f:?} should be falsey");
67 }
68 }
69
70 #[test]
71 fn process_running_finds_the_current_process_and_misses_a_bogus_one() {
72 assert!(process_running("entracte"), "should find the test binary");
77 assert!(!process_running("entracte-no-such-process-zzz"));
78 assert!(!process_running(" "));
79 }
80
81 #[test]
82 fn read_flag_reads_truthy_files_and_ignores_the_rest() {
83 let dir = crate::test_support::temp_dir();
84 let yes = dir.path().join("on.flag");
85 std::fs::write(&yes, "true").unwrap();
86 assert!(read_flag(&yes));
87
88 let no = dir.path().join("off.flag");
89 std::fs::write(&no, "0").unwrap();
90 assert!(!read_flag(&no));
91
92 assert!(!read_flag(&dir.path().join("missing.flag")));
93 assert!(!read_flag(dir.path()));
95
96 let binary = dir.path().join("binary.flag");
98 std::fs::write(&binary, [0xff, 0xfe, 0x00, 0x01]).unwrap();
99 assert!(!read_flag(&binary));
100 }
101
102 #[test]
103 fn read_flag_ignores_an_oversized_file() {
104 let dir = crate::test_support::temp_dir();
105 let big = dir.path().join("big.flag");
106 std::fs::write(&big, vec![b'1'; (MAX_FLAG_BYTES + 1) as usize]).unwrap();
107 assert!(!read_flag(&big));
108 }
109}