class

Termisu::Testing::Pty

Inherits Reference / Object

Allocates a pseudo-terminal and spawns a program attached to it, exposing the master side as an ordinary IO::FileDescriptor (read it for the child's output; write to it to deliver input).

SAFETY: spawning goes through Crystal's Process (a fork+exec the runtime is built for, child reaped via Process#wait). We never call a raw fork/forkpty — unsafe inside a GC'd, fibered runtime. The child adopts the PTY slave as its controlling terminal via the ctty-exec shim (see ctty_exec.cr), so a Termisu app's open("/dev/tty") resolves to our PTY.

Constants

CTTY_EXEC_SRC = {{ read_file("/tmp/tmp.dldNMk/src/src/termisu/testing/ctty_exec.cr") }}

Embedded shim source, so we don't depend on the .cr file existing at runtime.

Constructors

new(command : String, args : Array(String) = [] of String, *, cols : Int32 = 80, rows : Int32 = 24, env : Process::Env = nil)

Spawns command (with args) on a fresh PTY sized cols x rows.

Source

Class methods

ctty_exec_path
Source

Instance methods

close

Hangs up the child and releases the master fd. Idempotent.

Source
closed?
Source
master

The master side of the PTY. A PTY master is a character device, which Crystal treats as non-blocking, so fiber reads yield through the event loop.

Source
process

The spawned child. Signalling/reaping always target exactly this process.

Source
reap

Waits for the child to exit and returns its exit code (nil if signalled). Cached; intended to be called after the master reports EOF.

Source
resize(cols : Int32, rows : Int32) : Nil

Tells the kernel (and child) about new terminal geometry via TIOCSWINSZ.

Source
write(data : String | Bytes) : Nil

Writes input bytes to the child, flushing immediately (keystrokes must not sit buffered).

Source