Skip to content

Commit fc91cda

Browse files
Restore TTY when aborting TOTP ticker with Ctrl+C (#2342)
* Restore TTY when aborting TOTP ticker with Ctrl+C Fixes #2320 RELEASE_NOTES=[BUGFIX] Handle Ctrl+C in TOTP Signed-off-by: Dominik Schulz <[email protected]> * Disable parallel execution of non-concurrency safe tests Signed-off-by: Dominik Schulz <[email protected]> * Remove debug statement Signed-off-by: Dominik Schulz <[email protected]> Signed-off-by: Dominik Schulz <[email protected]>
1 parent 5b82b99 commit fc91cda

File tree

2 files changed

+29
-36
lines changed

2 files changed

+29
-36
lines changed

internal/action/otp.go

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -53,35 +53,35 @@ func tickingBar(ctx context.Context, expiresAt time.Time, bar *termio.ProgressBa
5353
}
5454
}
5555

56-
func waitForKeyPress(ctx context.Context, cancel context.CancelFunc) {
57-
tty, err := tty.Open()
56+
func waitForKeyPress(ctx context.Context, cancel context.CancelFunc) (func(), func()) {
57+
tty1, err := tty.Open()
5858
if err != nil {
5959
out.Errorf(ctx, "Unexpected error opening tty: %v", err)
6060
cancel()
6161
}
6262

63-
defer func() {
64-
_ = tty.Close()
65-
}()
63+
return func() {
64+
for {
65+
select {
66+
case <-ctx.Done():
67+
return // returning not to leak the goroutine.
68+
default:
69+
}
6670

67-
for {
68-
select {
69-
case <-ctx.Done():
70-
return // returning not to leak the goroutine.
71-
default:
72-
}
73-
74-
r, err := tty.ReadRune()
75-
if err != nil {
76-
out.Errorf(ctx, "Unexpected error opening tty: %v", err)
77-
}
71+
r, err := tty1.ReadRune()
72+
if err != nil {
73+
out.Errorf(ctx, "Unexpected error opening tty: %v", err)
74+
}
7875

79-
if r == 'q' || r == 'x' || err != nil {
80-
cancel()
76+
if r == 'q' || r == 'x' || err != nil {
77+
cancel()
8178

82-
return
79+
return
80+
}
81+
}
82+
}, func() {
83+
_ = tty1.Close()
8384
}
84-
}
8585
}
8686

8787
// nolint: cyclop
@@ -97,7 +97,9 @@ func (s *Action) otp(ctx context.Context, name, qrf string, clip, pw, recurse bo
9797
skip := ctxutil.IsHidden(ctx) || pw || qrf != "" || !ctxutil.IsTerminal(ctx) || !ctxutil.IsInteractive(ctx) || clip
9898
if !skip {
9999
// let us monitor key presses for cancellation:.
100-
go waitForKeyPress(ctx, cancel)
100+
runFn, cleanupFn := waitForKeyPress(ctx, cancel)
101+
go runFn()
102+
defer cleanupFn()
101103
}
102104

103105
// only used for the HOTP case as a fallback
@@ -188,6 +190,7 @@ func (s *Action) otp(ctx context.Context, name, qrf string, clip, pw, recurse bo
188190
select {
189191
case <-ctx.Done():
190192
bar.Done()
193+
cancel()
191194

192195
return nil
193196
default:

pkg/gopass/secrets/kv_test.go

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,15 @@ username: [email protected]
3535
Test / test.com
3636
`
3737

38-
t.Run("read back the secret", func(t *testing.T) {
39-
t.Parallel()
40-
38+
t.Run("read back the secret", func(t *testing.T) { //nolint:paralleltest
4139
assert.Equal(t, mlOut, string(s.Bytes()))
4240
})
4341

44-
t.Run("no_duplicate_keys", func(t *testing.T) {
45-
t.Parallel()
46-
42+
t.Run("no_duplicate_keys", func(t *testing.T) { //nolint:paralleltest
4743
assert.Equal(t, []string{"password", "url", "username"}, s.Keys())
4844
})
4945

50-
t.Run("read some keys", func(t *testing.T) {
51-
t.Parallel()
52-
46+
t.Run("read some keys", func(t *testing.T) { //nolint:paralleltest
5347
for k, v := range map[string]string{
5448
"password": "bar",
5549
"url": "http://www.test.com/",
@@ -62,9 +56,7 @@ Test / test.com
6256
assert.Equal(t, "somepasswd", s.Password())
6357
})
6458

65-
t.Run("remove a key", func(t *testing.T) {
66-
t.Parallel()
67-
59+
t.Run("remove a key", func(t *testing.T) { //nolint:paralleltest
6860
assert.NoError(t, s.Set("foobar", "baz"))
6961
v, ok := s.Get("foobar")
7062
assert.True(t, ok)
@@ -76,9 +68,7 @@ Test / test.com
7668
assert.Equal(t, "", v)
7769
})
7870

79-
t.Run("read the body", func(t *testing.T) {
80-
t.Parallel()
81-
71+
t.Run("read the body", func(t *testing.T) { //nolint:paralleltest
8272
body := "Test / test.com\n"
8373
assert.Equal(t, body, s.Body())
8474
assert.Equal(t, body, s.Body())

0 commit comments

Comments
 (0)