sbt/run
Brian Hotopp 0c03718218 [1.x] fix: Pump forked stdout/stderr to the captured active terminal (#9185)
Since #8678 (sbt 1.12.2), Fork.apply has routed the
`connectInput && outputStrategy == StdoutOutput` case through a new
JProcess path that calls `jpb.inheritIO()`. `inheritIO` ties the child
JVM's stdio to the sbt server JVM's OS-level fd 1/2, bypassing the
`Terminal` indirection. In server mode (which `sbt --client` uses),
that indirection is how task output reaches the client terminal — so
the child's stdout/stderr went nowhere observable to the client.

Keep `redirectInput(Redirect.INHERIT)` so REPL/raw-mode keystrokes
still reach the child (preserving the use case #8678 added), but
leave stdout/stderr as PIPE and pump them to the active terminal's
output/error streams in two daemon threads. The pump threads are
joined after `p.waitFor()` so all buffered output drains before the
task completes.

The active terminal is captured once on the task thread rather than
re-resolved per-write via the `System.out`/`err` proxies, otherwise a
concurrent terminal swap can route mid-pump bytes to the wrong client
(observed on the CI JDK 8 matrix; the proxy's `activeTerminal.get()`
is evaluated at every write).

Forced scala/scala3 CI to downgrade from sbt 1.12.10 to 1.12.1 (see
scala/scala3#25995).

Diagnosis credit: @mbovel in #9185.

Fixes sbt/sbt#9185.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 10:16:54 -04:00
..
src [1.x] fix: Pump forked stdout/stderr to the captured active terminal (#9185) 2026-05-25 10:16:54 -04:00
NOTICE Transfer copyright to Scala Center 2023-06-20 16:39:07 +02:00