fileutil

package
v0.12.4 Latest Latest
Warning

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

Go to latest
Published: May 8, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package fileutil provides atomic file writes and filesystem introspection helpers used across the kapm internal packages.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FlockExclusive added in v0.12.4

func FlockExclusive(f *os.File) error

FlockExclusive acquires an exclusive advisory lock on f.

func FlockUnlock added in v0.12.4

func FlockUnlock(f *os.File)

FlockUnlock releases the advisory lock on f.

func IsSymlinkMode

func IsSymlinkMode(m os.FileMode) bool

IsSymlinkMode reports whether m has the symlink bit set. Useful for inspecting os.FileMode returned by fs.DirEntry.Type() inside directory traversals where re-lstatting would be wasteful.

func IsSymlinkPath

func IsSymlinkPath(path string) (bool, error)

IsSymlinkPath reports whether path is a symlink. Returns (false, err) if path does not exist or Lstat fails. Returns (true, nil) if path exists and is a symlink. Returns (false, nil) if path exists but is not a symlink.

func OpenNoFollow added in v0.12.3

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

OpenNoFollow opens path read-only and refuses to follow a symlink at path. Uses O_NOFOLLOW for an atomic, race-free kernel-level check.

func OpenSafeLogFile added in v0.12.4

func OpenSafeLogFile(root, logDir, filename string) (*os.File, error)

OpenSafeLogFile opens (or creates) a log file at logDir/filename under root, guarding against symlink-based path traversal attacks.

The directory check is performed twice — before and after os.MkdirAll — to mitigate a TOCTOU race: an attacker could replace a legitimate directory with a symlink between the first check and the mkdir call. The post-mkdir check catches that substitution.

Returns the open file with an exclusive flock held. The caller is responsible for defer f.Close() and defer FlockUnlock(f).

func ReadFileNoFollow added in v0.12.3

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

ReadFileNoFollow opens path via OpenNoFollow, reads all contents, and closes. On Unix uses O_NOFOLLOW atomically; on Windows uses Lstat-before-open.

func RefuseSymlinkPath added in v0.11.0

func RefuseSymlinkPath(path string) error

RefuseSymlinkPath returns an error when path or an existing parent component is a symlink.

func RefuseSymlinkPathUnder added in v0.11.0

func RefuseSymlinkPathUnder(root, path string) error

RefuseSymlinkPathUnder returns an error when path or an existing parent component below root is a symlink. The root itself and its parents are treated as trusted, which avoids rejecting common platform layouts such as /tmp being a symlink while still protecting project-local managed paths.

func SymlinkInPath added in v0.11.0

func SymlinkInPath(path string) (string, bool, error)

SymlinkInPath returns the first existing symlink at path or in one of its existing parent components. Missing components stop the check and are not an error, so callers can run this before creating directories or files.

func WarnIfKapmSymlink(logsDir string)

WarnIfKapmSymlink emits a slog.Warn if the parent .kapm directory of logsDir is a symlink. It never returns an error (warn-only contract). Silent on missing path or lstat errors so startup is never blocked.

func WriteFileAtomic

func WriteFileAtomic(path string, data []byte, force bool) (written bool, err error)

WriteFileAtomic writes data to path atomically via a temp file + rename. If force is false and path already exists, returns (false, nil) without writing. Returns (true, nil) on successful write.

func WriteFilePair

func WriteFilePair(pathA string, dataA []byte, pathB string, dataB []byte, force bool) (bool, error)

WriteFilePair writes two files atomically as a pair: both files end up present on disk or neither is modified.

If force is false and either path already exists, returns (false, nil) without writing anything.

If force is true, both paths are overwritten via temp+rename. Symlinks at either destination are rejected before any write to prevent TOCTOU attacks. Both files are written with mode 0o644.

Rollback: if pathB's write fails after pathA has already been replaced, pathA is restored from a rename-to-sibling backup so that its original content, mode, and ownership are preserved.

Types

This section is empty.

Jump to

Keyboard shortcuts

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