diff --git a/src/state.rs b/src/state.rs index 54e374d..c7e540f 100644 --- a/src/state.rs +++ b/src/state.rs @@ -4,9 +4,46 @@ pub fn runtime_dir() -> PathBuf { if let Ok(dir) = std::env::var("RSS_STATE_DIR") { return PathBuf::from(dir); } + if let Some(dir) = discover_daemon_state_dir() { + return dir; + } PathBuf::from("/tmp/rss") } +fn discover_daemon_state_dir() -> Option { + let proc_dir = std::fs::read_dir("/proc").ok()?; + for entry in proc_dir { + let entry = entry.ok()?; + let pid = entry.file_name().to_str()?.to_string(); + if !pid.bytes().all(|b| b.is_ascii_digit()) { + continue; + } + let comm = std::fs::read_to_string(format!("/proc/{}/comm", pid)).ok()?; + if comm.trim() != "rss" { + continue; + } + let cmdline = std::fs::read(format!("/proc/{}/cmdline", pid)).ok()?; + let args: Vec<&str> = cmdline + .split(|&b| b == 0) + .filter_map(|s| std::str::from_utf8(s).ok()) + .collect(); + if !args.contains(&"daemon") { + continue; + } + let environ = std::fs::read(format!("/proc/{}/environ", pid)).ok()?; + for var in environ.split(|&b| b == 0) { + if let Ok(var_str) = std::str::from_utf8(var) { + if let Some(val) = var_str.strip_prefix("RSS_STATE_DIR=") { + if !val.is_empty() { + return Some(PathBuf::from(val)); + } + } + } + } + } + None +} + pub fn socket_path() -> PathBuf { if let Ok(p) = std::env::var("RSS_SOCKET") { return PathBuf::from(p);