From 027ff609365dd0775823b7cb45b8d2d06ee3a35d Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Sat, 15 Nov 2025 09:15:01 -0500 Subject: fix: handle stdin EOF in terminal detection and subprocess spawning ANSI.getTerminalSize queries the terminal by writing escape codes and reading the response from stdin. When stdin is unavailable or at EOF (common in non-interactive contexts), this causes "hWaitForInput: end of file" errors. Additionally, Conduit.streamingProcess returns a stdin handle that was never being closed, which could cause child processes to block waiting for input. Fixes: - Catch IOException in detectTerminal when getTerminalSize fails - Close subprocess stdin handle immediately after spawn - Fallback to default terminal size (80x24) when detection fails This unblocks all bild commands that were failing with stdin errors. --- Omni/Bild.hs | 3 ++- Omni/Log/Terminal.hs | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'Omni') diff --git a/Omni/Bild.hs b/Omni/Bild.hs index 4bb62a5..aac0d2d 100644 --- a/Omni/Bild.hs +++ b/Omni/Bild.hs @@ -1235,7 +1235,8 @@ run Proc {..} = do Conduit.proc cmd args |> (\proc_ -> proc_ {Process.create_group = True}) |> Conduit.streamingProcess - +> \(Conduit.UseProvidedHandle, stdout_, stderr_, hdl) -> + +> \(stdin_, stdout_, stderr_, hdl) -> do + IO.hClose stdin_ -- Close stdin immediately since we don't use it (,,) Async.Concurrently (loud ?: (puts stdout_, logs ns stdout_)) diff --git a/Omni/Log/Terminal.hs b/Omni/Log/Terminal.hs index 6d5d70c..a78e544 100644 --- a/Omni/Log/Terminal.hs +++ b/Omni/Log/Terminal.hs @@ -11,6 +11,7 @@ module Omni.Log.Terminal where import Alpha +import qualified Control.Exception as Exception import qualified Data.Text as Text import qualified System.Console.ANSI as ANSI import qualified System.Environment as Env @@ -40,8 +41,8 @@ detectTerminal = do (Nothing, _) -> False _ -> True - -- Get terminal size - mSize <- ANSI.getTerminalSize + -- Get terminal size, catching exceptions from stdin issues + mSize <- Exception.catch ANSI.getTerminalSize <| \(_ :: Exception.IOException) -> pure Nothing let (width, height) = case mSize of Just (h, w) -> (w, h) Nothing -> (80, 24) -- sensible default -- cgit v1.2.3