diff options
| author | Ben Sima <ben@bsima.me> | 2025-11-15 09:15:01 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bsima.me> | 2025-11-15 09:15:01 -0500 |
| commit | 027ff609365dd0775823b7cb45b8d2d06ee3a35d (patch) | |
| tree | 4780f4273a52ed9cd71b5a7af637767dfef28a19 | |
| parent | e8ff5ae65312229c67a6deb9235ce935709ae173 (diff) | |
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.
| -rw-r--r-- | Omni/Bild.hs | 3 | ||||
| -rw-r--r-- | Omni/Log/Terminal.hs | 5 |
2 files changed, 5 insertions, 3 deletions
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 (Conduit.waitForStreamingProcess hdl) <*> 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 |
