1 Commits
Author SHA1 Message Date
sneak 5df9dc098d Put the terminal back when a signal ends the mnemonic prompt (closes #91)
check / check (push) Waiting to run
A SIGINT, SIGTERM or SIGHUP at the mnemonic prompt killed the tool
with echo still off. The prompt now catches them with signals.Notify
from before echo goes off, and reads the line in a goroutine. Once the
line is read or a signal arrives, it puts the terminal settings back
and stops catching; if a signal has arrived by then, it sends the tool
the same signal again, so the tool is still ended by it (130 for SIGINT
in a shell). A signal the tool was started with set to be ignored stays
ignored. A test sends SIGINT at the prompt on a pseudo-terminal.

Unchanged: the Windows prompt, which uses term.ReadPassword.

Model: opus-5-5
2026-10-14 22:16:11 +00:00
6 changed files with 13 additions and 19 deletions
+3 -5
View File
@@ -65,12 +65,10 @@ calls into `internal/`. The packages there are:
and decrypts with it.
- `internal/childmnemonic` derives a child mnemonic from the main one using
BIP-85's own mnemonic application.
- `internal/signals` catches SIGINT, SIGTERM and SIGHUP for the commands that
clean up before they end, and for the mnemonic prompt, which puts the terminal
back before the signal ends the tool.
- `internal/cli` builds the cobra command tree and runs it. Under it,
`cli/options` holds the flags every command shares, and `cli/ssh`, `cli/age`
and `cli/mnemonic` are the command groups.
`cli/options` holds the flags every command shares, `cli/signals` catches
SIGINT, SIGTERM and SIGHUP for the commands that clean up before they end, and
`cli/ssh`, `cli/age` and `cli/mnemonic` are the command groups.
- `internal/bip39` is a copy of `github.com/tyler-smith/go-bip39` v1.1.0,
trimmed to what keyfunc uses.
+1 -1
View File
@@ -16,8 +16,8 @@ import (
"github.com/spf13/cobra"
"sneak.berlin/go/keyfunc/internal/agekey"
"sneak.berlin/go/keyfunc/internal/cli/options"
"sneak.berlin/go/keyfunc/internal/cli/signals"
"sneak.berlin/go/keyfunc/internal/derive"
"sneak.berlin/go/keyfunc/internal/signals"
)
// ErrInterrupted is returned when SIGINT, SIGTERM or SIGHUP has been
@@ -1,9 +1,5 @@
// Package signals catches SIGINT, SIGTERM and SIGHUP, the signals that
// end the tool, for the commands that clean up before they end and for
// the mnemonic prompt, which puts the terminal back before the signal
// ends the tool. Go keeps an inherited ignore only for SIGHUP and
// SIGINT, so a SIGTERM the tool was started with set to be ignored is
// not left ignored.
// Package signals catches the signals that end the tool, for the
// commands that clean up before they end.
package signals
import (
@@ -15,8 +11,8 @@ import (
// Context is signal.NotifyContext for SIGINT, SIGTERM and SIGHUP: the
// context it returns is cancelled when one of them arrives, and stop
// stops catching them. It leaves out SIGHUP or SIGINT if the tool was
// started with it set to be ignored, as nohup does with SIGHUP, because
// stops catching them. It leaves out any of the three the tool was
// started with set to be ignored, as nohup does with SIGHUP, because
// catching a signal turns an ignored one back on and would end a run
// that was meant to survive it.
func Context(parent context.Context) (context.Context, context.CancelFunc) {
@@ -41,8 +37,8 @@ func Notify(c chan<- os.Signal) {
}
}
// caught returns SIGINT, SIGTERM and SIGHUP, less any that
// signal.Ignored reports as ignored.
// caught returns those of SIGINT, SIGTERM and SIGHUP that the tool was
// not started with set to be ignored.
func caught() []os.Signal {
endings := []os.Signal{syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP}
kept := make([]os.Signal, 0, len(endings))
+1 -1
View File
@@ -15,8 +15,8 @@ import (
"time"
"github.com/spf13/cobra"
"sneak.berlin/go/keyfunc/internal/cli/signals"
"sneak.berlin/go/keyfunc/internal/mnemonic"
"sneak.berlin/go/keyfunc/internal/signals"
)
// Where the key goes on the host and what the file it arrives in is
+1 -1
View File
@@ -10,8 +10,8 @@ import (
"syscall"
"github.com/spf13/cobra"
"sneak.berlin/go/keyfunc/internal/cli/signals"
"sneak.berlin/go/keyfunc/internal/mnemonic"
"sneak.berlin/go/keyfunc/internal/signals"
)
// StatusError says the tool should end with the status ssh ended with.
+1 -1
View File
@@ -11,7 +11,7 @@ import (
"os/signal"
"golang.org/x/sys/unix"
"sneak.berlin/go/keyfunc/internal/signals"
"sneak.berlin/go/keyfunc/internal/cli/signals"
)
// readWithoutEcho reads one line from the terminal on standard input