mirror of
https://github.com/restic/restic.git
synced 2025-12-11 18:47:50 +00:00
Merge pull request #5554 from MichaelEischer/termstatus-flush
termstatus: flush before reading password from terminal
This commit is contained in:
7
changelog/unreleased/issue-5477
Normal file
7
changelog/unreleased/issue-5477
Normal file
@@ -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
|
||||||
@@ -44,6 +44,7 @@ type Terminal struct {
|
|||||||
type message struct {
|
type message struct {
|
||||||
line string
|
line string
|
||||||
err bool
|
err bool
|
||||||
|
barrier chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type status struct {
|
type status struct {
|
||||||
@@ -79,6 +80,7 @@ func Setup(stdin io.ReadCloser, stdout, stderr io.Writer, quiet bool) (*Terminal
|
|||||||
if term.outputWriter != nil {
|
if term.outputWriter != nil {
|
||||||
_ = term.outputWriter.Close()
|
_ = term.outputWriter.Close()
|
||||||
}
|
}
|
||||||
|
term.Flush()
|
||||||
// shutdown termstatus
|
// shutdown termstatus
|
||||||
cancel()
|
cancel()
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@@ -141,6 +143,7 @@ func (t *Terminal) InputRaw() io.ReadCloser {
|
|||||||
|
|
||||||
func (t *Terminal) ReadPassword(ctx context.Context, prompt string) (string, error) {
|
func (t *Terminal) ReadPassword(ctx context.Context, prompt string) (string, error) {
|
||||||
if t.InputIsTerminal() {
|
if t.InputIsTerminal() {
|
||||||
|
t.Flush()
|
||||||
return terminal.ReadPassword(ctx, int(t.inFd), t.errWriter, prompt)
|
return terminal.ReadPassword(ctx, int(t.inFd), t.errWriter, prompt)
|
||||||
}
|
}
|
||||||
if t.OutputIsTerminal() {
|
if t.OutputIsTerminal() {
|
||||||
@@ -177,6 +180,7 @@ func (t *Terminal) OutputWriter() io.Writer {
|
|||||||
// other option. Must not be used in combination with Print, Error, SetStatus
|
// other option. Must not be used in combination with Print, Error, SetStatus
|
||||||
// or any other method that writes to the terminal.
|
// or any other method that writes to the terminal.
|
||||||
func (t *Terminal) OutputRaw() io.Writer {
|
func (t *Terminal) OutputRaw() io.Writer {
|
||||||
|
t.Flush()
|
||||||
return t.wr
|
return t.wr
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,6 +214,10 @@ func (t *Terminal) run(ctx context.Context) {
|
|||||||
return
|
return
|
||||||
|
|
||||||
case msg := <-t.msg:
|
case msg := <-t.msg:
|
||||||
|
if msg.barrier != nil {
|
||||||
|
msg.barrier <- struct{}{}
|
||||||
|
continue
|
||||||
|
}
|
||||||
if terminal.IsProcessBackground(t.fd) {
|
if terminal.IsProcessBackground(t.fd) {
|
||||||
// ignore all messages, do nothing, we are in the background process group
|
// ignore all messages, do nothing, we are in the background process group
|
||||||
continue
|
continue
|
||||||
@@ -284,6 +292,10 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) {
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case msg := <-t.msg:
|
case msg := <-t.msg:
|
||||||
|
if msg.barrier != nil {
|
||||||
|
msg.barrier <- struct{}{}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var dst io.Writer
|
var dst io.Writer
|
||||||
if msg.err {
|
if msg.err {
|
||||||
@@ -307,6 +319,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) {
|
func (t *Terminal) print(line string, isErr bool) {
|
||||||
// make sure the line ends with a line break
|
// make sure the line ends with a line break
|
||||||
if len(line) == 0 || line[len(line)-1] != '\n' {
|
if len(line) == 0 || line[len(line)-1] != '\n' {
|
||||||
|
|||||||
@@ -124,7 +124,8 @@ func TestReadPasswordTerminal(t *testing.T) {
|
|||||||
func TestRawInputOutput(t *testing.T) {
|
func TestRawInputOutput(t *testing.T) {
|
||||||
input := io.NopCloser(strings.NewReader("password"))
|
input := io.NopCloser(strings.NewReader("password"))
|
||||||
var output bytes.Buffer
|
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, input, term.InputRaw())
|
||||||
rtest.Equals(t, false, term.InputIsTerminal())
|
rtest.Equals(t, false, term.InputIsTerminal())
|
||||||
rtest.Equals(t, &output, term.OutputRaw())
|
rtest.Equals(t, &output, term.OutputRaw())
|
||||||
|
|||||||
Reference in New Issue
Block a user