From f17027eeaa98e3ee5517b1836aabd56a13df5e1a Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 4 Oct 2025 23:06:57 +0200 Subject: [PATCH] termstatus: flush before reading password from terminal --- internal/ui/termstatus/status.go | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/internal/ui/termstatus/status.go b/internal/ui/termstatus/status.go index 3803882e6..79bb0a296 100644 --- a/internal/ui/termstatus/status.go +++ b/internal/ui/termstatus/status.go @@ -42,8 +42,9 @@ type Terminal struct { } type message struct { - line string - err bool + line string + err bool + barrier chan struct{} } type status struct { @@ -79,6 +80,7 @@ func Setup(stdin io.ReadCloser, stdout, stderr io.Writer, quiet bool) (*Terminal if term.outputWriter != nil { _ = term.outputWriter.Close() } + term.Flush() // shutdown termstatus cancel() wg.Wait() @@ -141,6 +143,7 @@ func (t *Terminal) InputRaw() io.ReadCloser { func (t *Terminal) ReadPassword(ctx context.Context, prompt string) (string, error) { if t.InputIsTerminal() { + t.Flush() return terminal.ReadPassword(ctx, int(t.inFd), t.errWriter, prompt) } if t.OutputIsTerminal() { @@ -210,6 +213,10 @@ func (t *Terminal) run(ctx context.Context) { return case msg := <-t.msg: + if msg.barrier != nil { + msg.barrier <- struct{}{} + continue + } if terminal.IsProcessBackground(t.fd) { // ignore all messages, do nothing, we are in the background process group continue @@ -284,6 +291,10 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) { case <-ctx.Done(): return case msg := <-t.msg: + if msg.barrier != nil { + msg.barrier <- struct{}{} + continue + } var dst io.Writer if msg.err { @@ -307,6 +318,20 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) { } } +// Flush waits for all pending messages to be printed. +func (t *Terminal) Flush() { + ch := make(chan struct{}) + defer close(ch) + select { + case t.msg <- message{barrier: ch}: + case <-t.closed: + } + select { + case <-ch: + case <-t.closed: + } +} + func (t *Terminal) print(line string, isErr bool) { // make sure the line ends with a line break if len(line) == 0 || line[len(line)-1] != '\n' {