Documentation
¶
Overview ¶
Package gitrun executes bounded, contained Git child processes for the CEM seams. Every failure is typed: cancellation, per-operation timeout, budget exhaustion, output-bound excess, start failure, and non-zero exit each carry a distinct registered code and are never collapsed into one another.
Containment: on Unix the child runs in its own process group. On every abnormal path (cancel, timeout, output excess) the whole group is killed BEFORE the child is reaped, so the group ID cannot be recycled while descendants are signalled. On the normal-exit path the group is swept immediately after the reap; the theoretical group-ID-reuse window there is accepted because the sweep is immediate and hostile same-UID interference is outside the approved trust boundary. Windows containment is deliberately not claimed here: Windows native execution is a separate unpromoted lane, and the stub kills only the direct child.
Index ¶
- Constants
- func PinBinary(path string)
- func Run(ctx context.Context, budget *Budget, options Options, args ...string) ([]byte, error)
- func RunReserved(ctx context.Context, perOp time.Duration, options Options, args ...string) ([]byte, error)
- func RunStream(ctx context.Context, budget *Budget, options Options, consumer io.Writer, ...) error
- type Budget
- type Options
- type Session
Constants ¶
const ( DefaultOperations = 1024 DefaultTotalBudget = 30 * time.Minute DefaultPerOpTimeout = 10 * time.Second DefaultStderrLimit = 64 << 10 )
Frozen operational bounds.
Variables ¶
This section is empty.
Functions ¶
func PinBinary ¶ added in v0.8.0
func PinBinary(path string)
PinBinary makes every later spawn with an empty Options.Binary run path, so a Git placed on PATH after a host started never runs (MCPV0-016). The caller passes an absolute path it already resolved; the CLI never pins.
func RunReserved ¶
func RunReserved(ctx context.Context, perOp time.Duration, options Options, args ...string) ([]byte, error)
RunReserved executes one bounded Git operation whose budget operation the caller already reserved, with perOp as its timeout. A Session request that must be replayed as its original one-shot invocation uses it, so the logical operation is charged exactly once.
func RunStream ¶
func RunStream(ctx context.Context, budget *Budget, options Options, consumer io.Writer, args ...string) error
RunStream sends stdout to a trusted, synchronous, nonblocking consumer. The consumer owns stdout's memory and framing bounds; StdoutLimit and StdoutSizeHint apply only to Run. All other process bounds remain in force. Consumer state is provisional until this call and its framing check succeed.
Types ¶
type Budget ¶
type Budget struct {
// contains filtered or unexported fields
}
Budget bounds one verification's Git usage: an operation count and a total wall deadline shared across operations.
func NewDefaultBudget ¶
func NewDefaultBudget() *Budget
NewDefaultBudget returns the frozen 1,024-operation, 30-minute budget.
type Options ¶
type Options struct {
Binary string // test seam; empty means the pinned Git, else "git"
Dir string
Env []string // complete child environment; nil means empty
Stdin []byte
StdoutLimit int
// StdoutSizeHint, when > 0, preallocates stdout's backing capacity to
// min(StdoutSizeHint, StdoutLimit) instead of growing it off nil capacity
// through Go's append growth ladder (roughly 5x the eventual payload).
// Set it only when the caller can compute the exact expected output size
// (e.g. a `git cat-file --batch` over blobs of known sizes); leave it
// zero when StdoutLimit is a generic ceiling unrelated to the actual
// output size, or preallocation would itself become the huge allocation.
StdoutSizeHint int
StderrLimit int // 0 means DefaultStderrLimit
PerOpTimeout time.Duration // 0 means DefaultPerOpTimeout
}
Options configure one bounded Git invocation.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session is one caller-scoped `git cat-file --batch` co-process answering requests in order. Its child starts on the first Read and ends at Close, so no process outlives the pass that owns the session. It charges no budget: the caller reserves one operation per request. A request the session cannot answer as one admitted record returns ok=false with the child already reaped; the caller then replays its original one-shot invocation, which alone classifies that failure. Only the per-operation timeout and cancellation are classified here, with Run's codes and messages.
func (*Session) Close ¶
func (s *Session) Close()
Close ends the session: the child sees EOF on stdin and exits; a child that does not exit within DefaultPerOpTimeout is killed with its group.
func (*Session) Read ¶
func (s *Session) Read(ctx context.Context, perOp time.Duration, options Options, args []string, request string, admit func(header string, fields []string, size int) bool) (string, []byte, bool, error)
Read writes request as one batch line and returns the record's header line and body when admit accepts the header line, its fields and the body size. A request holding LF or NUL is never written, so the stream cannot desynchronize.