git.lucas.co / cce-status-interface
status bar
git clone https://git.lucas.co/cce-status-interface.git

commit4dcda776e27405196751fc219678c5266b621d84
parentdf6de8e0fc
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-02 10:22
switcher listener: bound the trigger read in time and size

Connections are served one at a time, and read_line had no timeout, so
one that never finished its line left the Super+Tab switcher dead for the
rest of the session. The read is now capped at 4 KiB and 2s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 src/listeners.rs | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/listeners.rs b/src/listeners.rs
index 51ee090..eb0a48b 100644
--- a/src/listeners.rs
+++ b/src/listeners.rs
@@ -80,9 +80,15 @@ pub(crate) async fn spawn_switcher_listener(sender: calloop::channel::Sender<Cus
         log::info!("[switcher-listener] Listening on {}", socket_path);
         loop {
             if let Ok((stream, _)) = listener.accept().await {
-                let mut reader = tokio::io::BufReader::new(stream);
+                // Bounded in size and in TOTAL time: connections are served
+                // one at a time here, so one that never finished its line
+                // (until 2026-10-02 nothing timed it out) left the Super+Tab
+                // switcher dead for the rest of the session.
+                use tokio::io::AsyncReadExt;
+                let mut reader = tokio::io::BufReader::new(stream.take(4096));
                 let mut line = String::new();
-                if reader.read_line(&mut line).await.is_ok() {
+                let read = tokio::time::timeout(std::time::Duration::from_secs(2), reader.read_line(&mut line)).await;
+                if matches!(read, Ok(Ok(n)) if n > 0) {
                     let _ = sender.send(CustomEvent::SwitcherTriggered);
                 }
             }