Every command ends on SIGINT, SIGTERM or SIGHUP; an interrupted age -o leaves no file (closes #48)
check / check (push) Failing after 1s

SIGINT, SIGTERM and SIGHUP are no longer caught for the whole run, so they end any command at once, the mnemonic prompt included. One package, internal/cli/signals, catches them only where cleanup is needed, and only those not ignored at start, so nohup still works: ssh to and ssh install while their child runs, and age encrypt -o and age decrypt -o while they write. A signal received by the time the input ends leaves no new file and exits 1; otherwise the whole file is put in place, never an unfinished one.

Judgement call: the guarantee is stated for a signal keyfunc has received, as Go cannot promise more; the main goroutine stays on the main thread so a Ctrl-C on a pipeline is seen first on Linux. Unverified on macOS.

Model: opus-5-5 (implementation); fable-5-1 (design)
This commit was merged in pull request #54.
This commit is contained in:
2026-10-04 13:42:49 +02:00
parent 1d1c8182be
commit c96b77dd67
8 changed files with 491 additions and 50 deletions
+9
View File
@@ -13,6 +13,7 @@ import (
"strings"
"github.com/spf13/cobra"
"sneak.berlin/go/keyfunc/internal/cli/signals"
)
// Where the key goes on the host and what the file it arrives in is
@@ -62,6 +63,14 @@ func install() *cobra.Command {
return err
}
// From here on a signal cancels the context, which
// sftp runs under, instead of ending the tool, so sftp
// ends and the working directory is still removed.
ctx, stop := signals.Context(cmd.Context())
defer stop()
cmd.SetContext(ctx)
return add(cmd, args[0], args[1:], line)
},
}