Help us shape the future of Go! Take the 2026 Go Developer Survey

atomicfile

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package atomicfile provides permission-safe local state file helpers.

Index

Constants

View Source
const (
	PrivateDirMode  os.FileMode = 0o700
	PrivateFileMode os.FileMode = 0o600
)

Variables

This section is empty.

Functions

func ConvergePrivateFile

func ConvergePrivateFile(path string) error

ConvergePrivateFile validates an existing sensitive file and converges its permissions. Missing files are left untouched.

func EnsurePrivateDir

func EnsurePrivateDir(dir string) error

EnsurePrivateDir creates dir if needed and converges existing directories to owner-only permissions where POSIX modes are meaningful. It rejects symlinks, non-directories, and unsafe owner conditions when the platform exposes them.

func IsPublished

func IsPublished(err error) bool

IsPublished distinguishes a post-rename failure from an unpublished write.

func IsWindowsSharingError

func IsWindowsSharingError(err error) bool

IsWindowsSharingError recognises Windows sharing and access-denied errors, including wrapped errors. Callers apply it only on Windows.

func OpenSharedRead

func OpenSharedRead(path string) (*os.File, error)

OpenSharedRead opens path for reading. POSIX rename already replaces a directory entry while readers hold the previous file open.

func ReadFile

func ReadFile(path string) ([]byte, error)

ReadFile reads one shared snapshot, settling a transient missing name before its caller interprets absence. Bounded/special-file readers use the same ReadSettled and RetryFileOperation wrappers around their guarded read.

func ReadSettled

func ReadSettled(path string, read func() error) error

ReadSettled runs read once on non-Windows platforms. On Windows, when read reports that path does not exist, it reads again while one of this package's temporary files for path is present (a write or replacement is in progress), or immediately if path has reappeared. Absence with no such temporary file is returned as genuine. Other errors return unchanged. A temporary file left by a crashed writer delays a genuine not-exist result by at most the bounded sleep budget.

func ReplaceFile

func ReplaceFile(source, target string) error

ReplaceFile atomically replaces target with source.

func ReplacementInProgress

func ReplacementInProgress(path string) bool

ReplacementInProgress reports whether a temporary file created by this package's writers for path is present in path's directory.

func RetryFileOperation

func RetryFileOperation(operation func() error) error

RetryFileOperation is the shared Windows state-file policy: seven attempts for sharing/access errors, with 1, 2, 4, 8, 16 and 32 ms sleeps (63 ms total). The filesystem operation itself and OS scheduling are not time-bounded.

func RetrySharingViolation

func RetrySharingViolation(operation func() error, sleep func(time.Duration)) error

RetrySharingViolation implements the policy with an injectable sleep, so callers can test its budget without depending on the host scheduler.

func SetDirectorySyncForTest

func SetDirectorySyncForTest(fn func(string) error) func()

SetDirectorySyncForTest replaces the post-rename directory sync in an isolated test process. Call the returned function to restore it.

func WriteFile

func WriteFile(path string, data []byte) error

WriteFile writes data by creating a random exclusive temp file in the same directory, fsyncing it, atomically replacing path, and fsyncing the parent directory where the platform supports it. Pre-rename failures leave the old file in place and remove the temp file.

func WriteFileInExistingDir

func WriteFileInExistingDir(path string, data []byte, mode os.FileMode) error

WriteFileInExistingDir atomically writes a file without creating or changing the parent directory. It validates that the existing parent is a directory, is owned by the current user where ownership is available, and, on Unix, is not group- or world-writable. Windows does not expose DACLs through os.FileMode, so parent ownership and permissions are not validated there. Parent-directory symlinks and Windows junctions are followed and their referent is validated, while a symlink at path itself is rejected. The mode is caller policy and is applied exactly; callers choose any privacy floor.

func WriteFileInExistingDirWithReplace

func WriteFileInExistingDirWithReplace(path string, data []byte, mode os.FileMode, replace func(string, string) error) error

WriteFileInExistingDirWithReplace combines WriteFileInExistingDir's parent validation with WriteFileWithReplace's caller-owned replacement step: replace may retry the same fully written, synced and closed temporary file.

func WriteFileWithReplace

func WriteFileWithReplace(path string, data []byte, replace func(string, string) error) error

WriteFileWithReplace lets the caller replace one fully written, synced and closed temporary file using its platform-specific primitive and retry policy. The callback must replace source with target on success, and preserve both paths on failure. Preparation, target validation and cleanup remain shared.

Types

type PublishedError

type PublishedError struct{ Err error }

PublishedError means replacement succeeded, but its directory sync failed. The new bytes are visible; their durability across a crash is unconfirmed.

func (*PublishedError) Error

func (e *PublishedError) Error() string

func (*PublishedError) Unwrap

func (e *PublishedError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL