pty

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 4, 2022 License: MIT Imports: 7 Imported by: 1

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.

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
)

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 FdHolder

type FdHolder interface {
	Fd() uintptr
}

type Pty

type Pty interface {
	// Fd intended to resize Tty of 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(c *exec.Cmd) (pty Pty, err error)

Start 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.

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(cmd *exec.Cmd, ws *Winsize) (Pty, error)

StartWithSize 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.

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 {
	// 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