daemonlifecycle

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package daemonlifecycle provides the small cross-platform primitives shared by CLI daemons: owner-only state paths, advisory file locking, detached process start, and process identity.

It deliberately does not own a daemon's state machine, readiness protocol, timeouts, or recovery policy. Those remain product decisions. This package only keeps the security- and OS-sensitive mechanics identical across CLI implementations.

Index

Constants

This section is empty.

Variables

View Source
var ErrProcessMismatch = errors.New("process identity does not match")

ErrProcessMismatch reports that the pid now belongs to a different process than the one whose identity was recorded, typically after pid reuse.

View Source
var ErrProcessNotFound = errors.New("process not found")

ErrProcessNotFound reports that no running process has the requested pid. Exited processes that have not been reaped yet (zombies) count as not found.

Functions

func ConfigureDetached added in v0.13.0

func ConfigureDetached(command *exec.Cmd)

ConfigureDetached puts command's child in its own session, so it survives the process that started it, has no controlling terminal, and a later process-group signal stays scoped to that child and its descendants.

On Windows it sets DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | CREATE_BREAKAWAY_FROM_JOB and hides the window. Starting such a command fails with ERROR_ACCESS_DENIED inside a job that forbids breakaway; StartDetached handles that retry.

func Lock

func Lock(ctx context.Context, file *os.File, interval time.Duration) error

Lock waits for an exclusive advisory lock, polling at interval until ctx is cancelled. A non-positive interval uses 25 milliseconds.

func ProcessIdentity added in v0.13.0

func ProcessIdentity(pid int) (string, error)

ProcessIdentity returns an opaque token that names the running process pid for its whole life, so a pid recorded together with its identity can later be checked against the process that holds the pid now. Two calls for the same process return equal strings; a process that later reuses the pid gets a different one. Compare tokens only for equality and do not parse them.

The token is built from values the kernel records once and never recomputes, so wall-clock steps do not change it: on Linux the boot id plus the start time in clock ticks since boot, on macOS the kernel's start timeval, and on Windows the creation FILETIME.

It returns an error wrapping ErrProcessNotFound when no running process has that pid. It is implemented for Linux, macOS and Windows without cgo; other platforms return an error.

func ProtectOwnerOnly

func ProtectOwnerOnly(path string) error

ProtectOwnerOnly makes the current user the owner and replaces path's access policy with one granting access only to that user. Directories keep inheritable permissions for children.

func ProtectOwnerOnlyFile

func ProtectOwnerOnlyFile(file *os.File) error

ProtectOwnerOnlyFile makes the current user the owner and replaces an already-open file's access policy with one granting access only to that user. Consumers must subsequently call ValidateOwnerOnlyFile before trusting the handle. On Windows, applying the policy uses the file name because ordinary os.OpenFile handles do not carry WRITE_DAC; the handle-based validation detects any path replacement.

func StartDetached added in v0.13.0

func StartDetached(template *exec.Cmd, log *os.File) (*os.Process, error)

StartDetached starts the program described by template as a process that outlives its caller and never holds the caller's standard streams.

Only template's Path, Args, Env and Dir are used; template itself is never started, so its Stdin, Stdout, Stderr, ExtraFiles, SysProcAttr, Cancel and WaitDelay must be unset: a detached child does not follow a context. The child reads from the null device and writes both output streams to log, which the caller owns and may close once StartDetached returns. No other handle is inherited: on Unix every other descriptor is close-on-exec, and on Windows only the three standard handles are listed for inheritance. A caller whose own stdout is a pipe therefore sees EOF as soon as it exits, even while the child keeps running.

The child is configured with ConfigureDetached. On Windows, when the caller's job object forbids CREATE_BREAKAWAY_FROM_JOB and process creation fails with ERROR_ACCESS_DENIED, StartDetached retries once without the breakaway flag; that child stays in the job and dies with it, which the caller detects as a readiness failure.

The returned process is the caller's to Wait on (to observe an early exit) or Release. Readiness, timeouts and stopping remain the caller's policy.

func TerminateIfSameProcess added in v0.13.0

func TerminateIfSameProcess(pid int, identity string) error

TerminateIfSameProcess forcibly terminates pid only when its current identity equals identity, as returned earlier by ProcessIdentity. Otherwise it returns an error wrapping ErrProcessMismatch (or ErrProcessNotFound) and sends nothing.

On Windows the check and the termination use one process handle, so the pid cannot be reused in between. On Unix the check is immediately followed by SIGKILL; a pid reused within that instant is not distinguishable.

func TryLock

func TryLock(file *os.File) (bool, error)

TryLock obtains an exclusive non-blocking advisory lock on file.

func Unlock

func Unlock(file *os.File) error

Unlock releases a lock obtained with TryLock or Lock.

func ValidateOwnerOnly

func ValidateOwnerOnly(path string) error

ValidateOwnerOnly verifies that path is a regular file or directory whose effective access policy grants access only to the current user.

func ValidateOwnerOnlyFile

func ValidateOwnerOnlyFile(file *os.File) error

ValidateOwnerOnlyFile verifies the effective policy of an already-open regular file. Consumers that make security decisions after opening a lock or state file should prefer this handle-based form.

Types

This section is empty.

Jump to

Keyboard shortcuts

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