Documentation
¶
Overview ¶
Package fileutil provides shared helpers for file modes and for writing files that survive a crash, so every write site uses one source for permissions and one audited sequence of temp file, sync and rename.
The package logs nothing: it must not import internal/common/logger, which would be an import cycle, so every helper returns an error that names the file it concerns and leaves the logging to its caller.
Index ¶
Constants ¶
const CacheFileMode os.FileMode = 0600
CacheFileMode is the permission mode applied to cache and log files.
It is intentionally restrictive (0600 — owner-only read/write) because cache and log files may hold secrets or sensitive upstream metadata (for example credentials, tokens, or repository details). Group and world access is denied to avoid leaking that data to other local users.
Variables ¶
This section is empty.
Functions ¶
func PublishNewFile ¶
PublishNewFile creates path holding data under mode, and refuses to replace anything already there: the file is written to a temporary name exactly as WriteFileAtomic writes it, then hard-linked to path, which fails when any entry — a file, a directory, even a dangling symlink — already sits at path. That failure satisfies errors.Is(err, fs.ErrExist), the entry is left untouched, and no temporary file remains.
The link, unlike a check followed by a create, is one step: an entry created between a caller's existence check and the publish is never overwritten.
Any other error means nothing was published: when a step after the link fails — removing the temporary name or syncing the directory — the entry at path is removed again, but only while path still names the file this call linked, so an entry someone else put there in the meantime is left alone.
func RemoveStaleTemps ¶
RemoveStaleTemps removes the temporary files that writers killed mid-write left under root, and returns the paths it removed. A file is removed only when it is a regular file (a symlink is never followed or removed), its name matches the temporary-name pattern, and the PID in its name is no longer a live process. A temporary whose writer is alive — or whose PID answers EPERM, meaning it belongs to another user — is kept, so a concurrent writer is never robbed of its file.
With recursive false only root's own entries are examined; with recursive true the whole tree is, except any directory named .git. A failure to walk is wrapped naming root; a failure to remove one file is joined to the result naming that file, and the sweep goes on.
func WriteFileAtomic ¶
WriteFileAtomic replaces the file at path with data, under mode, so that a reader — or a crash — sees either the previous file or the new one and never a mixture.
The bytes go to a temporary file in path's own directory (so the rename never crosses a filesystem), named "." + base + ".bentoo-<pid>-<random>" so a leftover of a killed writer names the process that left it and is swept by RemoveStaleTemps. The temporary file is synced, closed with its error checked, and given mode before it is renamed over path; the parent directory is then synced so the rename itself survives a power loss.
Any failure before the rename removes the temporary file and leaves path byte-identical; the returned error wraps the cause and names path. A removal that itself fails is joined to the error, naming the file left behind — this package logs nothing.
Types ¶
This section is empty.