Documentation
¶
Overview ¶
Package atomicwrite provides TOCTOU-safe file writes using xxhash64 fingerprint verification, cross-platform file locking via gofrs/flock, atomic rename, and fsync for crash durability.
Index ¶
- Variables
- func Write(path string, data []byte) error
- func WriteFunc(path string, fn func(w io.Writer) error) error
- func WriteFuncVerified(path string, fn func(w io.Writer) error, fingerprint Fingerprint) error
- func WriteIfChanged(path string, data []byte) (bool, error)
- func WriteVerified(path string, data []byte, fingerprint Fingerprint) error
- func WriteWithPerm(path string, data []byte, perm fs.FileMode) error
- type Fingerprint
Constants ¶
This section is empty.
Variables ¶
var ErrConcurrentModification = errors.New("file was modified concurrently since read")
ErrConcurrentModification indicates the file was modified by another process between the fingerprint read and the write attempt.
Functions ¶
func Write ¶
Write writes data to path with crash durability (fsync + atomic rename). It does NOT perform TOCTOU verification — use WriteVerified for that. Use Write when concurrent modification is not a concern (e.g., temp files, first-time creation, or single-writer scenarios).
func WriteFunc ¶ added in v0.3.0
WriteFunc writes to path via a streaming callback with crash durability. The callback receives a buffered writer (64KB buffer) and may stream content incrementally without holding the full payload in memory. It does NOT perform TOCTOU verification — use WriteFuncVerified for that.
Use WriteFunc instead of Write when the content is large or produced incrementally (e.g., JSON encoders, diagram renderers).
func WriteFuncVerified ¶ added in v0.4.0
WriteFuncVerified writes to path via a streaming callback with TOCTOU protection and crash durability. See WriteVerified for fingerprint semantics.
func WriteIfChanged ¶ added in v0.4.0
WriteIfChanged writes data to path only if it differs from the current on-disk content. Returns changed=true if the file was written, false if the content was identical and the write was skipped.
This is the idiomatic primitive for config-file writers and code generators that must not produce spurious diffs on re-runs: no content change means no file mutation, no mtime bump, no file-watcher trigger.
Race-safe for existing files: if another process modifies the file between the fingerprint check and the atomic rename, returns ErrConcurrentModification. First-write (file does not exist) uses a plain atomic write — there is no prior content to protect.
func WriteVerified ¶ added in v0.4.0
func WriteVerified(path string, data []byte, fingerprint Fingerprint) error
WriteVerified writes data to path with TOCTOU protection and crash durability. Data is staged to a unique temp file, fsync'd, then verified against the fingerprint before atomic rename.
The fingerprint must be computed via FingerprintFile before reading/modifying the file. A zero-value fingerprint indicates the file should not yet exist; the write will fail with ErrConcurrentModification if another process creates it first. This prevents the silent-skip footgun where a caller forgets to compute a fingerprint.
func WriteWithPerm ¶ added in v0.5.0
WriteWithPerm writes data to path with an explicit file permission and crash durability (fsync + atomic rename). The temp file is created with the requested permission, so the final file appears atomically with the correct mode — there is no chmod-after-rename window in which the file is briefly visible with the wrong permissions.
The explicit permission takes precedence over an existing file's current mode. Use Write instead to preserve an existing file's mode (or the 0o644 default for new files).
It does NOT perform TOCTOU verification — use WriteVerified for that.
Types ¶
type Fingerprint ¶
type Fingerprint [8]byte
Fingerprint is an xxhash64 digest of file content at read time. A zero-value Fingerprint indicates no prior file existed.
func FingerprintFile ¶
func FingerprintFile(path string) (Fingerprint, error)
FingerprintFile computes an xxhash64 Fingerprint from a file's current content. Returns a zero-value Fingerprint if the file does not exist.
func FingerprintFromBytes ¶
func FingerprintFromBytes(data []byte) Fingerprint
FingerprintFromBytes computes an xxhash64 Fingerprint from raw content.
func (Fingerprint) IsZero ¶
func (fp Fingerprint) IsZero() bool
IsZero returns true if the fingerprint represents no prior file.
func (Fingerprint) Matches ¶
func (fp Fingerprint) Matches(content []byte) bool
Matches returns true if the given content produces the same fingerprint.