safeio

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package safeio implements bounded, identity-checked native filesystem operations without exposing file handles to policy code.

On Linux, a mutable root and each destination parent must be owned by the effective user and must not be writable by group or other. Safe cleanup moves owned bytes into a pinned owner-only directory before unlinking them. Writers running as that same trusted user must serialize mutations through safeio; Unix permissions cannot isolate mutually hostile processes with the same UID.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Code

type Code string

Code is a stable filesystem diagnostic identifier.

const (
	CodeOpen            Code = "CONTENT_IO_OPEN"
	CodeIdentityChanged Code = "CONTENT_IO_IDENTITY_CHANGED"
	CodeLinkRefused     Code = "CONTENT_IO_LINK_REFUSED"
	CodeBounds          Code = "CONTENT_IO_BOUNDS"
	CodeBusy            Code = "CONTENT_IO_BUSY"
	CodeDurability      Code = "CONTENT_IO_DURABILITY"
)

type Entry

type Entry struct {
	Path     string
	Identity Identity
}

Entry is one identity-checked regular file or directory below a Root. Path uses normalized forward slashes. Windows reports native Mode values: regular files have zero type bits and permission bits are not synthesized.

func (Entry) IsDir

func (entry Entry) IsDir() bool

type Error

type Error struct {
	Code      Code
	Operation string
	Path      string
	Retryable bool
	Err       error
}

Error describes a failed operation without exposing platform error details as policy decisions. Retryable is true only for transient sharing failures.

func (*Error) Error

func (err *Error) Error() string

func (*Error) Unwrap

func (err *Error) Unwrap() error

type FileTimes

type FileTimes struct {
	Accessed time.Time
	Modified time.Time
}

FileTimes contains deterministic regular-file access and modification times. Values are normalized to UTC microsecond precision on every platform.

type Identity

type Identity struct {
	Volume uint64
	File   uint64
	Size   int64
	Mode   fs.FileMode
	Links  uint64
}

Identity is a native object identity and observed metadata. Mode is native: Windows reports directory/type information but zero permission bits; callers map separately authenticated logical content modes instead of inferring them.

func (Identity) SameFile

func (left Identity) SameFile(right Identity) bool

SameFile reports whether two observations refer to the same native object.

type Root

type Root struct {
	// contains filtered or unexported fields
}

Root confines operations to one native directory handle.

func OpenRoot

func OpenRoot(path string) (*Root, error)

OpenRoot opens and pins a directory used as the boundary for later relative operations. Call Close when the root is no longer needed.

func (*Root) Close

func (root *Root) Close() error

func (*Root) Enumerate

func (root *Root) Enumerate(maximumEntries int) ([]Entry, error)

Enumerate returns every regular file and directory below the pinned root in lexicographic UTF-8 byte order. maximumEntries counts all directory entries, including entries rejected as links or unsupported types. Enumeration counts before allocating its result and verifies the complete membership and native identities in a second descriptor-relative pass.

func (*Root) HashFile

func (root *Root) HashFile(relative string, maximumBytes int64) (string, Identity, error)

HashFile streams at most maximumBytes through SHA-256 and verifies identity and size before returning.

func (*Root) Inspect

func (root *Root) Inspect(relative string) (Identity, error)

Inspect observes a regular file without following a final symlink or reparse point.

func (*Root) ReadFile

func (root *Root) ReadFile(relative string, maximumBytes int64) (Snapshot, error)

ReadFile reads at most maximumBytes and rejects identity or size changes that occur during the read.

func (*Root) Remove

func (root *Root) Remove(relative string, expected *Identity) error

Remove durably removes a file, optionally conditioned on its current native identity.

func (*Root) Stage

func (root *Root) Stage(
	destination string,
	source io.Reader,
	expectedBytes int64,
	maximumBytes int64,
	mode fs.FileMode,
) (*Staged, error)

Stage copies exactly expectedBytes from source to a durable temporary file. maximumBytes is an independent hard bound and mode must be non-executable. Unix applies all permission bits exactly. Windows applies its exact native mapping: owner-write controls FILE_ATTRIBUTE_READONLY and ACLs stay inherited.

func (*Root) StageDirectory

func (root *Root) StageDirectory(
	destination string,
	mode fs.FileMode,
) (*StagedDirectory, error)

StageDirectory creates an unpublished private directory beside destination. mode is exact on Unix. Windows directories retain inherited ACLs because FileMode cannot losslessly encode a DACL; owner rwx and no group/other writes remain mandatory policy inputs on every platform.

type Snapshot

type Snapshot struct {
	Bytes    []byte
	SHA256   string
	Identity Identity
}

Snapshot is a bounded file read and its verified post-read identity.

type Staged

type Staged struct {
	// contains filtered or unexported fields
}

Staged is a durable temporary regular file owned by a Root. A caller must choose exactly one terminal operation: CommitReplace or Discard.

func (*Staged) CommitReplace

func (staged *Staged) CommitReplace(destination string, expected *Identity) error

CommitReplace atomically publishes a staged file. When expected is non-nil, replacement fails unless the destination still has that identity.

func (*Staged) Discard

func (staged *Staged) Discard() error

Discard durably removes an unpublished staged file. It is idempotent.

func (*Staged) Identity

func (staged *Staged) Identity() Identity

func (*Staged) SHA256

func (staged *Staged) SHA256() string

func (*Staged) SetTimes

func (staged *Staged) SetTimes(times FileTimes) error

SetTimes applies deterministic access and modification times to the pinned staged handle. Stage applies the Unix epoch by default; callers may override it after the write and before the terminal operation.

func (*Staged) Size

func (staged *Staged) Size() int64

type StagedDirectory

type StagedDirectory struct {
	// contains filtered or unexported fields
}

StagedDirectory is one private directory tree assembled below a confined Root. The tree remains unpublished until CommitNoReplace and never replaces an existing destination.

func (*StagedDirectory) CommitNoReplace

func (staged *StagedDirectory) CommitNoReplace(destination string) error

CommitNoReplace durably publishes the complete tree if destination is absent.

func (*StagedDirectory) Discard

func (staged *StagedDirectory) Discard() error

Discard durably removes an unpublished staged tree. It is idempotent.

func (*StagedDirectory) Root

func (staged *StagedDirectory) Root() *Root

Root returns the pinned, private root used to populate the staged tree. Callers must stop using it before CommitNoReplace or Discard.

Jump to

Keyboard shortcuts

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