discover daemon state dir from cmdline when environ is unreadable
When the daemon runs as a different user (e.g. via systemd), the client cannot read /proc/<pid>/environ due to permissions. Fall back to parsing the cmdline for -D / --state-dir flags, which are world-readable. Fixes 'error: no logs for <service>' when client and daemon run as different users. v0.1.1
This commit is contained in:
parent
032f0ded69
commit
e4aea785ee
2 changed files with 32 additions and 7 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rss"
|
name = "rss"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
||||||
37
src/state.rs
37
src/state.rs
|
|
@ -30,16 +30,41 @@ fn discover_daemon_state_dir() -> Option<PathBuf> {
|
||||||
if !args.contains(&"daemon") {
|
if !args.contains(&"daemon") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let environ = std::fs::read(format!("/proc/{}/environ", pid)).ok()?;
|
// Try RSS_STATE_DIR from environ first
|
||||||
for var in environ.split(|&b| b == 0) {
|
if let Ok(environ) = std::fs::read(format!("/proc/{}/environ", pid)) {
|
||||||
if let Ok(var_str) = std::str::from_utf8(var) {
|
for var in environ.split(|&b| b == 0) {
|
||||||
if let Some(val) = var_str.strip_prefix("RSS_STATE_DIR=") {
|
if let Ok(var_str) = std::str::from_utf8(var) {
|
||||||
if !val.is_empty() {
|
if let Some(val) = var_str.strip_prefix("RSS_STATE_DIR=") {
|
||||||
return Some(PathBuf::from(val));
|
if !val.is_empty() {
|
||||||
|
return Some(PathBuf::from(val));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Fallback: parse cmdline for -D / --state-dir (works across users)
|
||||||
|
let mut i = 0;
|
||||||
|
while i < args.len() {
|
||||||
|
let next = if args[i] == "-D" || args[i] == "--state-dir" {
|
||||||
|
args.get(i + 1).map(|s| s.to_string())
|
||||||
|
} else if let Some(val) = args[i].strip_prefix("--state-dir=") {
|
||||||
|
Some(val.to_string())
|
||||||
|
} else if let Some(val) = args[i].strip_prefix("-D") {
|
||||||
|
if val.is_empty() {
|
||||||
|
args.get(i + 1).map(|s| s.to_string())
|
||||||
|
} else {
|
||||||
|
Some(val.to_string())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if let Some(dir) = next {
|
||||||
|
if !dir.is_empty() {
|
||||||
|
return Some(PathBuf::from(dir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue