ssh/tailssh: hold CHANNEL_EOF until both output streams drain
The previous commit sent CHANNEL_EOF from the stdout copier as soon as stdout hit EOF. With the process exited and the send window exhausted by a slow client, the stderr copier could still be draining its backlog; x/crypto/ssh fails every write after EOF (WriteExtended checks sentEOF), so the tail of stderr was silently dropped. Send CloseWrite from run() itself, after cmd.Wait, exit-status and both output copiers have finished. Wire order is unchanged: exit-status, remaining output, EOF, CHANNEL_CLOSE. The test withholds stderr window credit until the process has exited server-side, then releases it and checks the final bytes arrived. It also pins the harness login shell to /bin/sh; fish forks -c commands and stays resident, changing pipe fd ownership under test. Updates #18256 Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
K
Kristoffer Dalby committed
dd426dbb51b5e625096b7afa09b62da189550df8
Parent: 92f4300
Committed by Kristoffer Dalby <kristoffer@dalby.cc>
on 7/30/2026, 8:18:00 AM