ptyproc

package
v0.0.0-...-797f5bb Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package ptyproc owns the process and PTY lifecycle for tuitest: spawning a child attached to a pseudo-terminal, pumping its output, resizing, EOF and exit-code handling, and process-tree teardown. It is deliberately separate from the screen-matching logic so the two compose independently (the go-expect separation of console ownership from expectation matching).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Probe

func Probe(cols, rows int) error

Probe reports whether a pseudo-terminal can be allocated at all, by opening one and immediately closing it. It spawns no child, so it is safe to call from diagnostics without risking a stray process. A non-nil error is the reason allocation failed, which on a container without /dev/pts is exactly what a user needs to see.

Types

type Config

type Config struct {
	Argv []string // argv[0] is the program, argv[1:] the arguments
	Env  []string // full environment ("KEY=VALUE" entries)
	Dir  string   // working directory, empty for inherit
	Cols int
	Rows int
}

Config configures a spawn.

type Handler

type Handler struct {
	// OnData is called with each chunk read from the PTY master. The slice is
	// owned by the callback for the duration of the call only.
	OnData func([]byte)
	// OnClose is called once, after the child has exited and been reaped, with
	// its exit code (-1 if unknown).
	OnClose func(code int)
}

Handler receives lifecycle callbacks from the pump goroutine. Callbacks are invoked from a single dedicated goroutine, never concurrently with each other, so the receiver only needs to guard state it also touches elsewhere.

type Process

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

Process is a spawned child attached to a PTY.

func Start

func Start(cfg Config, h Handler) (*Process, error)

Start spawns the configured child in a new PTY and starts pumping output.

func (*Process) Close

func (p *Process) Close() error

Close tears down the whole process tree and closes the PTY. It is idempotent and safe to call from a cleanup hook even after the child exited.

It returns a non-nil error when something the child spawned was still running after SIGKILL, or failing that when the PTY could not be released. Both are leaks the caller needs to know about, the process one most of all: a test that ignores it hands the next test a machine with stray processes on it, which is how a suite ends up flooding a workstation.

func (*Process) Done

func (p *Process) Done() <-chan struct{}

Done returns a channel closed once the child has been reaped and the Handler's OnClose callback has returned.

func (*Process) ExitCode

func (p *Process) ExitCode() (int, bool)

ExitCode reports the child's exit code and whether it has exited.

The code is -1 for a child that died from a signal, which is what os.ProcessState.ExitCode reports and not the shell's 128+signal convention: a harness that invented 137 for SIGKILL would be unable to tell it apart from a program that genuinely exited 137. It is also -1 before the child has exited at all, so the second return value is the only thing that separates the two, and ExitStatus is what distinguishes a crash from an ordinary failure.

func (*Process) ExitStatus

func (p *Process) ExitStatus() (Status, bool)

ExitStatus reports how the child finished, including signal death, and whether it has exited at all.

func (*Process) Pid

func (p *Process) Pid() int

Pid returns the child's process id, or 0 if it never started.

func (*Process) Resize

func (p *Process) Resize(cols, rows int) error

Resize changes the PTY window size; the kernel delivers SIGWINCH to the child.

func (*Process) Write

func (p *Process) Write(b []byte) error

Write sends input bytes to the child. Write sends bytes to the child. Two goroutines write here: the caller sending keystrokes, and the output pump forwarding emulator query responses. The lock keeps a short write from being interleaved into the middle of an escape sequence from the other writer.

type Status

type Status struct {
	Code     int
	Signaled bool
	Signal   syscall.Signal
}

Status describes how a child finished. Code is the exit status, or -1 when the child died from a signal or the status could not be read. Signaled and Signal separate a real crash (SIGSEGV, SIGABRT, SIGBUS) from an ordinary non-zero exit, which ExitCode alone flattens to -1 and loses.

Jump to

Keyboard shortcuts

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