From aa25719c0d43effe8fe9962e5b72cb9884470efc Mon Sep 17 00:00:00 2001 From: harald Date: Mon, 14 Sep 2026 13:27:10 +0200 Subject: [PATCH] fix(linux): prevent premature unmount caused by closed channel triggers in select! --- src/mount.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/src/mount.rs b/src/mount.rs index 0c3bf1c..482b1d7 100644 --- a/src/mount.rs +++ b/src/mount.rs @@ -156,7 +156,9 @@ pub async fn mount_container( ) -> Result<()> { let drive_str = format_drive(drive_letter); let _ = mount_point; + let _ = open_explorer; let _ = enable_tray; + let _ = lock_on_screen_lock; if !container_path.exists() { bail!( @@ -298,11 +300,13 @@ pub async fn mount_container( } // Optional automatisch im Windows Explorer öffnen (visuelle Parität für Decoy und Hidden Vault) + #[cfg(windows)] if open_explorer { let _ = crate::windows::open_in_explorer(drive_letter); } - // System-Tray Initialisierung + // System-Tray Initialisierung (nur Windows) + #[cfg(windows)] let (_tray_shutdown_tx, mut tray_shutdown_rx) = tokio::sync::mpsc::channel::<()>(1); #[cfg(windows)] let _tray = if enable_tray { @@ -335,8 +339,6 @@ pub async fn mount_container( } else { None }; - #[cfg(not(windows))] - let _tray: Option<()> = None; // Inaktivitäts-Timer (Auto-Lock) let (idle_shutdown_tx, mut idle_shutdown_rx) = tokio::sync::mpsc::channel::<()>(1); @@ -362,8 +364,10 @@ pub async fn mount_container( } } - // Windows-Sitzungssperre (Win + L Auto-Lock) + // Windows-Sitzungssperre (Win + L Auto-Lock, nur Windows) + #[cfg(windows)] let (session_lock_tx, mut session_lock_rx) = tokio::sync::mpsc::channel::<()>(1); + #[cfg(windows)] let _session_monitor = if lock_on_screen_lock { match crate::windows::start_session_lock_monitor(session_lock_tx) { Ok(guard) => Some(guard), @@ -431,11 +435,20 @@ pub async fn mount_container( println!(); } - // Windows Console Close Monitor (CTRL_CLOSE_EVENT / CTRL_SHUTDOWN_EVENT) + // Windows Console Close Monitor (CTRL_CLOSE_EVENT / CTRL_SHUTDOWN_EVENT, nur Windows) + #[cfg(windows)] let (console_close_tx, mut console_close_rx) = tokio::sync::mpsc::channel::<()>(1); + #[cfg(windows)] let _console_guard = crate::windows::start_console_ctrl_monitor(console_close_tx, drive_letter).ok(); + // Unix Signale (SIGTERM, SIGHUP) + #[cfg(unix)] + let mut sigterm = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()).ok(); + #[cfg(unix)] + let mut sighup = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::hangup()).ok(); + // Warten auf Beendigungssignal (Ctrl+C, Tray-Klick, Inaktivität, Win+L, Konsolenfenster-Schließen) + #[cfg(windows)] tokio::select! { res = tokio::signal::ctrl_c() => { let _ = res; @@ -444,25 +457,81 @@ pub async fn mount_container( println!(" {} Beendigungssignal (Ctrl+C) empfangen.", ui::yellow("[!]")); } } - _ = console_close_rx.recv() => { + Some(()) = console_close_rx.recv() => { if !stealth { println!(); println!(" {} Konsolenfenster wird geschlossen — sichere Trennung ausgeführt!", ui::yellow("[!]")); } } - _ = tray_shutdown_rx.recv() => { + Some(()) = tray_shutdown_rx.recv() => { if !stealth { println!(); println!(" {} Beendigungssignal aus System-Tray empfangen.", ui::yellow("[!]")); } } - _ = session_lock_rx.recv() => { + Some(()) = session_lock_rx.recv() => { if !stealth { println!(); println!(" {} Windows-Sitzung gesperrt (Win + L) — Auto-Lock ausgelöst!", ui::yellow("[!]")); } } - _ = idle_shutdown_rx.recv() => { + Some(()) = idle_shutdown_rx.recv() => { + if !stealth { + println!(); + println!(" {} Inaktivitäts-Timeout erreicht — Auto-Lock ausgelöst!", ui::yellow("[!]")); + } + } + } + + #[cfg(unix)] + tokio::select! { + res = tokio::signal::ctrl_c() => { + let _ = res; + if !stealth { + println!(); + println!(" {} Beendigungssignal (Ctrl+C) empfangen.", ui::yellow("[!]")); + } + } + _ = async { + match sigterm.as_mut() { + Some(s) => { s.recv().await; } + None => { std::future::pending::<()>().await; } + } + } => { + if !stealth { + println!(); + println!(" {} Beendigungssignal (SIGTERM) empfangen.", ui::yellow("[!]")); + } + } + _ = async { + match sighup.as_mut() { + Some(s) => { s.recv().await; } + None => { std::future::pending::<()>().await; } + } + } => { + if !stealth { + println!(); + println!(" {} Beendigungssignal (SIGHUP) empfangen.", ui::yellow("[!]")); + } + } + Some(()) = idle_shutdown_rx.recv() => { + if !stealth { + println!(); + println!(" {} Inaktivitäts-Timeout erreicht — Auto-Lock ausgelöst!", ui::yellow("[!]")); + } + } + } + + #[cfg(not(any(windows, unix)))] + tokio::select! { + res = tokio::signal::ctrl_c() => { + let _ = res; + if !stealth { + println!(); + println!(" {} Beendigungssignal (Ctrl+C) empfangen.", ui::yellow("[!]")); + } + } + Some(()) = idle_shutdown_rx.recv() => { if !stealth { println!(); println!(" {} Inaktivitäts-Timeout erreicht — Auto-Lock ausgelöst!", ui::yellow("[!]"));