Signals end every command, not only ssh to and ssh install (closes #48)
check / check (push) Successful in 2m35s

SIGINT, SIGTERM and SIGHUP were caught for the whole run, but only the
ssh and sftp children acted on them: the mnemonic prompt waited for
Enter, and an interrupted `age encrypt -o` went on to put the
encryption of the cut-off input in place. Now only `ssh to` and
`ssh install` catch them, from once the mnemonic is read until their
cleanup has run; everywhere else they end the tool at once. Tests cover
an interrupted `age encrypt -o` and the install working directory on a
signal.

Model: opus-5-5
This commit is contained in:
2026-10-04 04:40:57 +00:00
parent 1ddc2c747a
commit ca1faa5551
6 changed files with 163 additions and 22 deletions
+14 -3
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"os"
"os/exec"
"os/signal"
"slices"
"syscall"
@@ -42,7 +43,17 @@ func to() *cobra.Command {
return err
}
served, err := key.Serve(cmd.Context(), comment)
// From here until the agent is taken down, a signal
// cancels the context instead of ending the tool, so
// ssh ends and the socket and its directory are still
// removed.
ctx, stop := signal.NotifyContext(
cmd.Context(),
syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP,
)
defer stop()
served, err := key.Serve(ctx, comment)
if err != nil {
return err
}
@@ -53,7 +64,7 @@ func to() *cobra.Command {
"-o", "IdentityAgent=" + served.Socket(),
}, args)
return connect(cmd.Context(), argv)
return connect(ctx, argv)
},
}
@@ -76,7 +87,7 @@ func connect(ctx context.Context, argv []string) error {
command.Stdout = os.Stdout
command.Stderr = os.Stderr
// A cancelled context means a signal ended the tool. Send ssh a
// A cancelled context means a signal arrived. Send ssh a
// SIGTERM rather than the default kill, so it puts the terminal
// back the way it found it before it goes.
command.Cancel = func() error {