Put the terminal back when a signal ends the mnemonic prompt (closes #91)
check / check (push) Canceled after 0s

A SIGINT, SIGTERM or SIGHUP at the mnemonic prompt killed the tool
with echo still off. The prompt now catches them 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 test sends SIGINT at the prompt on a pseudo-terminal.

The signals package moves from internal/cli to internal/signals, since
the mnemonic prompt now uses it as well.

Untested: a signal that comes just as the line is read.

Model: opus-5-5
This commit was merged in pull request #92.
This commit is contained in:
2026-10-15 01:35:42 +02:00
parent a08eb28359
commit 8bb3d949d9
8 changed files with 175 additions and 52 deletions
+10 -7
View File
@@ -65,10 +65,12 @@ 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, `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.
`cli/options` holds the flags every command shares, 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.
@@ -328,10 +330,11 @@ passes through `ssh`'s own exit status.
SIGINT, SIGTERM and SIGHUP end any command at once, at the mnemonic prompt too,
with the status a shell gives a program killed by that signal (130 for SIGINT).
While `age encrypt -o` or `age decrypt -o` is writing a new file or replacing a
regular one, the signal makes it remove the unfinished file, leave a file
already at the named path as it was, and exit with status 1. That holds for a
signal that has reached `keyfunc` when its input ends; a later one leaves the
At the prompt the terminal's settings are put back as they were first, so echo
is on again. While `age encrypt -o` or `age decrypt -o` is writing a new file or
replacing a regular one, the signal makes it remove the unfinished file, leave a
file already at the named path as it was, and exit with status 1. That holds for
a signal that has reached `keyfunc` when its input ends; a later one leaves the
whole file in place. Ctrl-C on a pipeline ends the input at the same moment, and
on Linux `keyfunc` sees the signal first, though no system promises that. A
named pipe or a device at the `-o` path, or a path that is the same file as