Write encrypt and decrypt output only once they succeed (closes #143)
check / check (push) Waiting to run

`secret encrypt` and `secret decrypt` emptied the file named by
`--output` before reading any input, so a failure left it empty, and a
file given as both `--input` and `--output` was emptied before it was
read. They now write into a temporary file of mode 0600 next to it, or
next to the file it is a symbolic link to, and rename that over it only
on success, with the new `secret.WriteFileAtomicFunc`. An output file
that cannot be written still fails. Ctrl-C, SIGTERM or a hangup removes
the temporary file. A device or pipe, such as `/dev/null`, is written to
directly.

Judgement calls: the device and pipe case; a command started with
`nohup` still ignores a hangup.

Model: opus-5-5
This commit is contained in:
2026-10-14 21:59:00 +00:00
parent 72cd6c30a1
commit e4a866949b
8 changed files with 616 additions and 54 deletions
+13
View File
@@ -283,6 +283,19 @@ generates a new Age key.
Decrypts data using an Age key stored as a secret.
Both write the result to a new file next to `--output` and rename it over
`--output` only once they have succeeded, so a failed command leaves an existing
`--output` as it was and creates none, and `--input` and `--output` can be the
same file. When `--output` is a symbolic link, the file it points to is
replaced, or created if it does not exist yet, and the link kept; the new file
is then made next to that file. The directory the new file is made in must be
writable. The new file has mode 0600 and belongs to the user running the
command, whatever mode and owner the file it replaces had, so a hard link to the
old file keeps the old content. Ctrl-C, SIGTERM or a hangup removes the new
file; a command killed any other way, such as with SIGKILL, leaves it there,
named `.tmp-` and a number. A device or a pipe, such as `/dev/null`, is written
to directly.
## Storage Architecture
### Directory Structure