diff --git a/src-tauri/src/commands/program.rs b/src-tauri/src/commands/program.rs index ca7bbfd..c14a1e7 100644 --- a/src-tauri/src/commands/program.rs +++ b/src-tauri/src/commands/program.rs @@ -398,19 +398,107 @@ pub struct MemoryCard { pub has_original: bool, } -/// Mounted removable media, wherever this OS puts it. macOS mounts under -/// /Volumes; Windows gives each card a drive letter. Both are cheap to -/// enumerate and neither needs any permission the app does not already have. +/// Mounted removable media, wherever this OS puts it. Windows gives each card a +/// drive letter; macOS mounts under /Volumes; Linux has no fixed place at all, +/// so its mount table is read instead. None of the three needs any permission +/// the app does not already have. +/// +/// Split three ways on purpose rather than "Windows, or else". #106 shipped +/// because Linux fell through to the macOS branch, read a `/Volumes` that does +/// not exist there, and swallowed the error: on a platform with published +/// installers, no microSD card was ever detected and nothing said why. A fourth +/// platform now fails to build rather than inheriting whichever branch it lands +/// in. fn mounted_roots() -> Vec { - if cfg!(target_os = "windows") { + #[cfg(target_os = "windows")] + { ('D'..='Z') .map(|d| std::path::PathBuf::from(format!("{d}:\\"))) .collect() - } else { + } + + #[cfg(target_os = "macos")] + { std::fs::read_dir("/Volumes") .map(|rd| rd.flatten().map(|e| e.path()).collect()) .unwrap_or_default() } + + #[cfg(target_os = "linux")] + { + // Unreadable /proc/mounts means "no cards", the same as an empty one: + // the manual picker is always there, and a card is not worth an error + // dialog about procfs. + parse_proc_mounts(&std::fs::read_to_string("/proc/mounts").unwrap_or_default()) + } + + #[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))] + compile_error!( + "mounted_roots: this platform's convention for removable media is unknown — give it \ + its own branch instead of inheriting another OS's (#106)" + ); +} + +/// Mount points from `/proc/mounts` that could be a radio's card. +/// +/// Linux mounts removable media through udisks2, which puts it under +/// `/media//