mod.rs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. use std::collections::HashMap;
  2. use std::path::PathBuf;
  3. use std::sync::OnceLock;
  4. #[cfg(target_os = "linux")]
  5. mod linux;
  6. #[cfg(target_os = "macos")]
  7. mod macos;
  8. #[cfg(target_os = "linux")]
  9. use linux::mounts;
  10. #[cfg(target_os = "macos")]
  11. use macos::mounts;
  12. /// Details of a mounted filesystem.
  13. #[derive(Clone)]
  14. pub struct MountedFs {
  15. pub dest: PathBuf,
  16. pub fstype: String,
  17. pub source: String,
  18. }
  19. #[derive(Debug)]
  20. #[non_exhaustive]
  21. pub enum Error {
  22. #[cfg(target_os = "macos")]
  23. GetFSStatError(i32),
  24. #[cfg(target_os = "linux")]
  25. IOError(std::io::Error)
  26. }
  27. impl std::error::Error for Error {}
  28. impl std::fmt::Display for Error {
  29. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  30. // Allow unreachable_patterns for windows build
  31. #[allow(unreachable_patterns)]
  32. match self {
  33. #[cfg(target_os = "macos")]
  34. Error::GetFSStatError(err) => write!(f, "getfsstat failed: {err}"),
  35. #[cfg(target_os = "linux")]
  36. Error::IOError(err) => write!(f, "failed to read /proc/mounts: {err}"),
  37. _ => write!(f, "Unknown error"),
  38. }
  39. }
  40. }
  41. // A lazily initialised static map of all mounted file systems.
  42. //
  43. // The map contains a mapping from the mounted directory path to the
  44. // corresponding mount information. If there's an error retrieving the mount
  45. // list or if we're not running on Linux or Mac, the map will be empty.
  46. //
  47. // Initialise this at application start so we don't have to look the details
  48. // up for every directory. Ideally this would only be done if the --mounts
  49. // option is specified which will be significantly easier once the move
  50. // to `clap` is complete.
  51. pub(super) fn all_mounts() -> &'static HashMap<PathBuf, MountedFs> {
  52. static ALL_MOUNTS: OnceLock<HashMap<PathBuf, MountedFs>> = OnceLock::new();
  53. ALL_MOUNTS.get_or_init(|| {
  54. // Allow unused_mut for windows build
  55. #[allow(unused_mut)]
  56. let mut mount_map: HashMap<PathBuf, MountedFs> = HashMap::new();
  57. #[cfg(any(target_os = "linux", target_os = "macos"))]
  58. if let Ok(mounts) = mounts() {
  59. for mount in mounts {
  60. mount_map.insert(mount.dest.clone(), mount);
  61. }
  62. }
  63. mount_map
  64. })
  65. }