From f17027eeaa98e3ee5517b1836aabd56a13df5e1a Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 4 Oct 2025 23:06:57 +0200 Subject: [PATCH 1/3] 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' { From 30ed992af98ecde54dbe1e85df1d4a2762a8a7a0 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 4 Oct 2025 23:08:48 +0200 Subject: [PATCH 2/3] termstatus: flush output before returning OutputRaw() writer This prevents mangling the output due to delayed messages. --- internal/ui/termstatus/status.go | 1 + internal/ui/termstatus/status_test.go | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/ui/termstatus/status.go b/internal/ui/termstatus/status.go index 79bb0a296..3265c7a04 100644 --- a/internal/ui/termstatus/status.go +++ b/internal/ui/termstatus/status.go @@ -180,6 +180,7 @@ func (t *Terminal) OutputWriter() io.Writer { // other option. Must not be used in combination with Print, Error, SetStatus // or any other method that writes to the terminal. func (t *Terminal) OutputRaw() io.Writer { + t.Flush() return t.wr } diff --git a/internal/ui/termstatus/status_test.go b/internal/ui/termstatus/status_test.go index f6b885cee..f65bb096f 100644 --- a/internal/ui/termstatus/status_test.go +++ b/internal/ui/termstatus/status_test.go @@ -124,7 +124,8 @@ func TestReadPasswordTerminal(t *testing.T) { func TestRawInputOutput(t *testing.T) { input := io.NopCloser(strings.NewReader("password")) var output bytes.Buffer - term := New(input, &output, io.Discard, false) + term, cancel := Setup(input, &output, io.Discard, false) + defer cancel() rtest.Equals(t, input, term.InputRaw()) rtest.Equals(t, false, term.InputIsTerminal()) rtest.Equals(t, &output, term.OutputRaw()) From e320ef0a6266e22b2dfd7249f767a2b7ab0c745d Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 4 Oct 2025 23:15:07 +0200 Subject: [PATCH 3/3] add changelog --- changelog/unreleased/issue-5477 | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 changelog/unreleased/issue-5477 diff --git a/changelog/unreleased/issue-5477 b/changelog/unreleased/issue-5477 new file mode 100644 index 000000000..f56cca84b --- /dev/null +++ b/changelog/unreleased/issue-5477 @@ -0,0 +1,7 @@ +Bugfix: Password prompt was sometimes not shown + +The password prompt for a repository was sometimes not shown when running +the `backup -v` command. This has been fixed. + +https://github.com/restic/restic/issues/5477 +https://github.com/restic/restic/pull/5554