pty

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Nov 19, 2024 License: MIT Imports: 8 Imported by: 0

README

pty

Pty is a Go package for using unix pseudo-terminals and windows ConPty.

Install

go get github.com/creack/pty

Examples

Note that those examples are for demonstration purpose only, to showcase how to use the library. They are not meant to be used in any kind of production environment. If you want to set deadlines to work and Close() interrupting Read() on the returned *os.File, you will need to call syscall.SetNonblock manually.

NOTE: This package requires ConPty support on windows platform, please make sure your windows system meet these requirements

Command
package main

import (
	"io"
	"os"
	"os/exec"

	"github.com/creack/pty"
)

func main() {
	c := exec.Command("grep", "--color=auto", "bar")
	f, err := pty.Start(c)
	if err != nil {
		panic(err)
	}

	go func() {
		f.Write([]byte("foo\n"))
		f.Write([]byte("bar\n"))
		f.Write([]byte("baz\n"))
		f.Write([]byte{4}) // EOT
	}()
	io.Copy(os.Stdout, f)
}
Shell
package main

import (
        "io"
        "log"
        "os"
        "os/exec"
        "os/signal"
        "syscall"

        "github.com/creack/pty"
        "golang.org/x/term"
)

func test() error {
        // Create arbitrary command.
        c := exec.Command("bash")

        // Start the command with a pty.
        ptmx, err := pty.Start(c)
        if err != nil {
                return err
        }
        // Make sure to close the pty at the end.
        defer func() { _ = ptmx.Close() }() // Best effort.

        // Handle pty size.
        ch := make(chan os.Signal, 1)
        signal.Notify(ch, syscall.SIGWINCH)
        go func() {
                for range ch {
                        if err := pty.InheritSize(os.Stdin, ptmx); err != nil {
                                log.Printf("error resizing pty: %s", err)
                        }
                }
        }()
        ch <- syscall.SIGWINCH // Initial resize.
        defer func() { signal.Stop(ch); close(ch) }() // Cleanup signals when done.

        // Set stdin in raw mode.
        oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
        if err != nil {
                panic(err)
        }
        defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.

        // Copy stdin to the pty and the pty to stdout.
        // NOTE: The goroutine will keep reading until the next keystroke before returning.
        go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
        _, _ = io.Copy(os.Stdout, ptmx)

        return nil
}

func main() {
        if err := test(); err != nil {
                log.Fatal(err)
        }
}

Documentation

Overview

Package pty provides functions for working with Unix terminals.

Index

Constants

View Source
const (
	TIOCGWINSZ = syscall.TIOCGWINSZ
	TIOCSWINSZ = syscall.TIOCSWINSZ
)

Local syscall const values.

Variables

View Source
var ErrUnsupported = errors.New("unsupported")

ErrUnsupported is returned if a function is not available on the current platform.

Functions

func Getsize

func Getsize(t FdHolder) (rows, cols int, err error)

Getsize returns the number of rows (lines) and cols (positions in each line) in terminal t.

func InheritSize

func InheritSize(pty Pty, tty Tty) error

InheritSize applies the terminal size of pty to tty. This should be run in a signal handler for syscall.SIGWINCH to automatically resize the tty when the pty receives a window size change notification.

func Open

func Open() (Pty, Tty, error)

Open a pty and its corresponding tty.

func Setsize

func Setsize(t FdHolder, ws *Winsize) error

Setsize resizes t to s.

Types

type DeadlineHolder

type DeadlineHolder interface {
	SetDeadline(t time.Time) error
}

DeadlineHolder surfaces the SetDeadline() method to sets the read and write deadlines.

type FdHolder

type FdHolder interface {
	Fd() uintptr
}

FdHolder surfaces the Fd() method of the underlying handle.

type Pty

type Pty interface {
	// FdHolder is intended to resize / control ioctls of the TTY of the child process in current process.
	FdHolder

	Name() string

	// WriteString is only used to identify Pty and Tty.
	WriteString(s string) (n int, err error)

	io.ReadWriteCloser
}

Pty for terminal control in current process.

  • For Unix systems, the real type is *os.File.
  • For Windows, the real type is a *WindowsPty for ConPTY handle.

func Start

func Start(cmd *exec.Cmd) (Pty, error)

Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, and c.Stderr, calls c.Start, and returns the File of the tty's corresponding pty.

Starts the process in a new session and sets the controlling terminal.

func StartWithAttrs

func StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (Pty, error)

StartWithAttrs assigns a pseudo-terminal Tty to c.Stdin, c.Stdout, and c.Stderr, calls c.Start, and returns the File of the tty's corresponding Pty.

This will resize the Pty to the specified size before starting the command if a size is provided. The `attrs` parameter overrides the one set in c.SysProcAttr.

This should generally not be needed. Used in some edge cases where it is needed to create a pty without a controlling terminal.

func StartWithSize

func StartWithSize(c *exec.Cmd, sz *Winsize) (Pty, error)

StartWithSize assigns a pseudo-terminal Tty to c.Stdin, c.Stdout, and c.Stderr, calls c.Start, and returns the File of the tty's corresponding Pty.

This will resize the Pty to the specified size before starting the command. Starts the process in a new session and sets the controlling terminal.

type Tty

type Tty interface {
	// FdHolder Fd only intended for manual InheritSize from Pty.
	FdHolder

	Name() string

	io.ReadWriteCloser
}

Tty for data I/O in child process.

  • For Unix systems, the real type is *os.File.
  • For Windows, the real type is a *WindowsTty, which is a combination of two pipe file.

type Winsize

type Winsize struct {
	Rows uint16 // ws_row: Number of rows (in cells).
	Cols uint16 // ws_col: Number of columns (in cells).
	X    uint16 // ws_xpixel: Width in pixels.
	Y    uint16 // ws_ypixel: Height in pixels.
}

Winsize describes the terminal size.

func GetsizeFull

func GetsizeFull(t FdHolder) (size *Winsize, err error)

GetsizeFull returns the full terminal size description.

Jump to

Keyboard shortcuts

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