pty

package
v0.4.3 Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Overview

Package pty provides pseudo-terminal (PTY) primitives for running interactive applications within child processes.

A pseudo-terminal is a pair of virtual file descriptors that behave like a real terminal. It allows programs that expect to be connected to a terminal (vim, htop, bash, etc.) to run as subprocesses of a Go application.

Terminology

The PTY pair uses the following naming convention:

  • Controller: the application side. Read process output from it; write input to it.
  • Worker: the process side. Attached to the child process as its stdin, stdout, and stderr.

Platform Support

Usage

cmd := proc.NewCmd(ctx, "vim", "file.txt")
pty, err := pty.StartPTY(cmd)
if err != nil {
    log.Fatal(err)
}
defer pty.Controller.Close()

// pty.Controller is an *os.File; use io.Copy for streaming I/O.
go io.Copy(os.Stdout, pty.Controller)
io.Copy(pty.Controller, os.Stdin)
cmd.Wait()

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrUnsupported = errors.New("pty: PTY is not supported on this platform")

ErrUnsupported is returned by StartPTY on platforms where pseudo-terminal allocation is not implemented.

Functions

This section is empty.

Types

type PTY

type PTY struct {
	// Controller is the application-side end of the PTY.
	// Read from it to receive process output; write to it to send input.
	// Call Close() on the PTY instead of closing this file directly.
	Controller *os.File

	// Worker is the process-side end of the PTY.
	// It is passed to the child process as its stdio; it is closed in the
	// parent by [StartPTY] after the process starts.
	Worker *os.File
	// contains filtered or unexported fields
}

PTY holds the two ends of a pseudo-terminal pair.

func StartPTY

func StartPTY(cmd *exec.Cmd) (*PTY, error)

StartPTY starts cmd attached to a newly allocated pseudo-terminal. It returns a PTY whose Controller the caller should use to read output from and write input to the process.

StartPTY does NOT apply proc package hygiene attributes (Job Objects / Pdeathsig). Use [proc.NewCmd] and [proc.Start] for that; StartPTY simply replaces cmd.Start():

cmd := proc.NewCmd(ctx, "vim", "file.txt")
pty, err := pty.StartPTY(cmd)

On platforms where PTY is not supported, StartPTY returns ErrUnsupported.

Example
package main

import (
	"context"
	"fmt"
	"os/exec"
	"time"

	"github.com/aretw0/procio/pty"
)

func main() {
	// A basic demonstration of creating an interactive PTY session.
	// Note: PTY behavior varies wildly between Windows/Linux.

	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancel()

	cmd := exec.CommandContext(ctx, "echo", "interactive")

	// StartPTY attaches the command's std streams to a new terminal
	pt, err := pty.StartPTY(cmd)
	if err != nil {
		fmt.Printf("Failed to start PTY: %v\n", err)
		return
	}
	defer pt.Controller.Close()

	// You can now Read/Write from pt.Controller to interact
	// with the child process as if it were a terminal.

	_ = cmd.Wait()
	fmt.Println("PTY session handled")
}

func (*PTY) Close

func (p *PTY) Close() error

Close closes the PTY controller and tears down associated kernel objects (like Windows PseudoConsoles). It returns the first error encountered, if any.

Jump to

Keyboard shortcuts

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