Skip to content

Commit

Permalink
fix!: create IPC socket in user runtime directory
Browse files Browse the repository at this point in the history
Each user has their own runtime directory at `/run/user/<uid>`. Creating
the IPC socket in there makes sure it is cleaned up regardless of
whether `ncspot` exits normally.

BREAKING CHANGE: move IPC socket location
  • Loading branch information
ThomasFrans committed Oct 21, 2023
1 parent a69e2d7 commit 905353c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
6 changes: 4 additions & 2 deletions src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::library::Library;
use crate::queue::Queue;
use crate::spotify::{PlayerEvent, Spotify};
use crate::ui::create_cursive;
use crate::{authentication, ui};
use crate::{authentication, ui, utils};
use crate::{command, queue, spotify};

#[cfg(feature = "mpris")]
Expand Down Expand Up @@ -165,7 +165,9 @@ impl Application {
#[cfg(unix)]
let ipc = ipc::IpcSocket::new(
ASYNC_RUNTIME.get().unwrap().handle(),
crate::config::cache_path("ncspot.sock"),
utils::create_runtime_directory()
.unwrap()
.join("ncspot.sock"),
event_manager.clone(),
)
.map_err(|e| e.to_string())?;
Expand Down
46 changes: 45 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(dead_code)]

use std::fmt::Write;
use std::{fmt::Write, path::PathBuf};

/// Returns a human readable String of a Duration
///
Expand Down Expand Up @@ -59,3 +59,47 @@ pub fn download(url: String, path: std::path::PathBuf) -> Result<(), std::io::Er
std::io::copy(&mut resp, &mut file)?;
Ok(())
}

/// Create the application specific runtime directory and return the path to it.
///
/// If the directory already exists and has the correct permissions, this function just returns the
/// existing directory. The contents stored in this directory are not necessarily persisted across
/// reboots. Stored files should be small since they could reside in memory (like on a tmpfs mount).
#[cfg(unix)]
pub fn create_runtime_directory() -> Result<PathBuf, Box<dyn std::error::Error>> {
use std::fs;

let linux_runtime_directory =
PathBuf::from(format!("/run/user/{}/", unsafe { libc::getuid() }));
let unix_runtime_directory = PathBuf::from("/tmp/");

let user_runtime_directory = if let Some(xdg_runtime_directory) = xdg_runtime_directory() {
Some(xdg_runtime_directory.join("ncspot"))
} else if cfg!(linux) && linux_runtime_directory.exists() {
Some(linux_runtime_directory.join("ncspot"))
} else if unix_runtime_directory.exists() {
Some(unix_runtime_directory.join(format!("ncspot-{}", unsafe { libc::getuid() })))
} else {
None
}
.ok_or("no runtime directory found")?;

let creation_result = fs::create_dir(&user_runtime_directory);

if creation_result.is_ok()
|| matches!(
creation_result.as_ref().unwrap_err().kind(),
std::io::ErrorKind::AlreadyExists
)
{
Ok(user_runtime_directory)
} else {
#[allow(clippy::unnecessary_unwrap)]
Err(Box::new(creation_result.unwrap_err()))
}
}

#[cfg(unix)]
fn xdg_runtime_directory() -> Option<PathBuf> {
std::env::var("XDG_RUNTIME_DIR").ok().map(Into::into)
}

0 comments on commit 905353c

Please sign in to comment.