aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.rs38
-rw-r--r--src/daemon.rs14
2 files changed, 37 insertions, 15 deletions
diff --git a/src/config.rs b/src/config.rs
index 67cb366..f20fb3a 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -303,9 +303,39 @@ impl Config {
303 } 303 }
304 304
305 pub fn get_socket_path() -> PathBuf { 305 pub fn get_socket_path() -> PathBuf {
306 let runtime_dir = std::env::var("XDG_RUNTIME_DIR") 306 runtime_dir().join("daemon.sock")
307 .map(PathBuf::from)
308 .unwrap_or_else(|_| PathBuf::from("/tmp"));
309 runtime_dir.join("rsplayer").join("daemon.sock")
310 } 307 }
311} 308}
309
310/// Directory holding the daemon socket and PID file.
311///
312/// Uses the user's XDG state directory (~/.local/state/rsplayer) so the path
313/// is identical no matter how the daemon was started (rc.d service, login
314/// shell, ...). The previous XDG_RUNTIME_DIR-based path depended on the
315/// environment and broke the service/CLI handshake on FreeBSD, where
316/// XDG_RUNTIME_DIR is often unset (falling back to the world-writable
317/// /tmp/rsplayer).
318pub fn runtime_dir() -> PathBuf {
319 if let Some(base) = directories::BaseDirs::new()
320 && let Some(state) = base.state_dir()
321 {
322 return state.join("rsplayer");
323 }
324 // Fallback when no home/state dir is resolvable
325 std::env::var("XDG_RUNTIME_DIR")
326 .map(PathBuf::from)
327 .unwrap_or_else(|_| PathBuf::from("/tmp"))
328 .join("rsplayer")
329}
330
331/// Create the runtime directory (private, 0700) and return its path.
332pub fn ensure_runtime_dir() -> std::io::Result<PathBuf> {
333 let dir = runtime_dir();
334 std::fs::create_dir_all(&dir)?;
335 #[cfg(unix)]
336 {
337 use std::os::unix::fs::PermissionsExt;
338 std::fs::set_permissions(&dir, std::fs::Permissions::from_mode(0o700))?;
339 }
340 Ok(dir)
341}
diff --git a/src/daemon.rs b/src/daemon.rs
index 279620d..21f1a3b 100644
--- a/src/daemon.rs
+++ b/src/daemon.rs
@@ -203,13 +203,8 @@ pub fn start_daemon() -> Result<(), Box<dyn std::error::Error>> {
203 std::fs::remove_file(&socket_path).ok(); 203 std::fs::remove_file(&socket_path).ok();
204 } 204 }
205 205
206 // Create runtime directory 206 // Create runtime directory (private, 0700)
207 if let Some(parent) = socket_path.parent() { 207 crate::config::ensure_runtime_dir()?;
208 std::fs::create_dir_all(parent)?;
209 }
210 if let Some(parent) = pid_path.parent() {
211 std::fs::create_dir_all(parent)?;
212 }
213 208
214 // Write PID file 209 // Write PID file
215 let pid = std::process::id(); 210 let pid = std::process::id();
@@ -1609,10 +1604,7 @@ fn find_audio_in_dir(dir: &Path) -> Option<Vec<std::path::PathBuf>> {
1609 1604
1610/// Get the PID file path for the daemon 1605/// Get the PID file path for the daemon
1611fn get_pid_path(_config: &Config) -> std::path::PathBuf { 1606fn get_pid_path(_config: &Config) -> std::path::PathBuf {
1612 let runtime_dir = std::env::var("XDG_RUNTIME_DIR") 1607 crate::config::runtime_dir().join("rsplayer.pid")
1613 .map(std::path::PathBuf::from)
1614 .unwrap_or_else(|_| std::path::PathBuf::from("/tmp"));
1615 runtime_dir.join("rsplayer").join("rsplayer.pid")
1616} 1608}
1617 1609
1618/// Check if a process with the given PID is running 1610/// Check if a process with the given PID is running