| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- use std::collections::HashMap;
- use std::path::PathBuf;
- use std::sync::OnceLock;
- #[cfg(target_os = "linux")]
- mod linux;
- #[cfg(target_os = "macos")]
- mod macos;
- #[cfg(target_os = "linux")]
- use linux::mounts;
- #[cfg(target_os = "macos")]
- use macos::mounts;
- /// Details of a mounted filesystem.
- #[derive(Clone)]
- pub struct MountedFs {
- pub dest: PathBuf,
- pub fstype: String,
- pub source: String,
- }
- #[derive(Debug)]
- #[non_exhaustive]
- pub enum Error {
- #[cfg(target_os = "macos")]
- GetFSStatError(i32),
- #[cfg(target_os = "linux")]
- IOError(std::io::Error)
- }
- impl std::error::Error for Error {}
- impl std::fmt::Display for Error {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- // Allow unreachable_patterns for windows build
- #[allow(unreachable_patterns)]
- match self {
- #[cfg(target_os = "macos")]
- Error::GetFSStatError(err) => write!(f, "getfsstat failed: {err}"),
- #[cfg(target_os = "linux")]
- Error::IOError(err) => write!(f, "failed to read /proc/mounts: {err}"),
- _ => write!(f, "Unknown error"),
- }
- }
- }
- // A lazily initialised static map of all mounted file systems.
- //
- // The map contains a mapping from the mounted directory path to the
- // corresponding mount information. If there's an error retrieving the mount
- // list or if we're not running on Linux or Mac, the map will be empty.
- //
- // Initialise this at application start so we don't have to look the details
- // up for every directory. Ideally this would only be done if the --mounts
- // option is specified which will be significantly easier once the move
- // to `clap` is complete.
- pub(super) fn all_mounts() -> &'static HashMap<PathBuf, MountedFs> {
- static ALL_MOUNTS: OnceLock<HashMap<PathBuf, MountedFs>> = OnceLock::new();
- ALL_MOUNTS.get_or_init(|| {
- // Allow unused_mut for windows build
- #[allow(unused_mut)]
- let mut mount_map: HashMap<PathBuf, MountedFs> = HashMap::new();
- #[cfg(any(target_os = "linux", target_os = "macos"))]
- if let Ok(mounts) = mounts() {
- for mount in mounts {
- mount_map.insert(mount.dest.clone(), mount);
- }
- }
- mount_map
- })
- }
|