termio

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package termio provides interruptible I/O primitives and terminal handling.

It solves common issues with blocking I/O in Go CLI tools, particularly on Windows, where a blocked read from stdin can prevent signal delivery or cause hangs.

Key features:

  • InterruptibleReader: A reader that respects context cancellation.
  • Open: Platform-safe terminal opening (uses CONIN$ on Windows).
  • Upgrade: Automatic detection and upgrade of readers to terminal-aware handles.

Index

Constants

This section is empty.

Variables

View Source
var ErrInterrupted = errors.New("interrupted")

Functions

func IsInterrupted

func IsInterrupted(err error) bool

IsInterrupted checks if the error is related to an interruption (Context Canceled, ErrInterrupted, or EOF).

func IsTerminal

func IsTerminal(f *os.File) bool

IsTerminal checks if the given file is a terminal. For now, we rely on basic checks or x/term if needed, but for simple cases we just assume it's okay. We might add x/term dependency later if we need IsTerminal check.

func Open

func Open() (io.ReadCloser, error)

Open returns the standard input reader. On POSIX, it simply returns os.Stdin.

func Upgrade added in v0.1.1

func Upgrade(r io.Reader) (io.Reader, error)

Upgrade checks if the provided reader is a file-based terminal. If it is, it upgrades it to a safe terminal reader (like CONIN$ on Windows) using Open(). If it is not (e.g. pipe, file, buffer), it returns the original reader.

Types

type InterruptibleReader

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

InterruptibleReader wraps an io.Reader and checks for cancellation before and after reads. Note: The underlying Read() call may still block! This wrapper primarily ensures that if the context is cancelled *before* we read, we return immediately, and if cancelled *during* the read (and the read returns), we prioritize the cancellation error.

func NewInterruptibleReader

func NewInterruptibleReader(base io.Reader, cancel <-chan struct{}) *InterruptibleReader

NewInterruptibleReader returns a reader that checks the cancel channel.

func (*InterruptibleReader) Read

func (r *InterruptibleReader) Read(p []byte) (n int, err error)

Jump to

Keyboard shortcuts

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