pty.go

  1package pty
  2
  3import (
  4	"context"
  5	"errors"
  6	"io"
  7	"os"
  8	"syscall"
  9)
 10
 11var (
 12	// ErrInvalidCommand is returned when the command is invalid.
 13	ErrInvalidCommand = errors.New("pty: invalid command")
 14)
 15
 16// New returns a new pseudo-terminal.
 17func New() (Pty, error) {
 18	return newPty()
 19}
 20
 21// Pty is a pseudo-terminal interface.
 22type Pty interface {
 23	io.ReadWriteCloser
 24
 25	// Name returns the name of the pseudo-terminal.
 26	// On Windows, this will always be "windows-pty".
 27	// On Unix, this will return the name of the slave end of the
 28	// pseudo-terminal TTY.
 29	Name() string
 30
 31	// Command returns a command that can be used to start a process
 32	// attached to the pseudo-terminal.
 33	Command(name string, args ...string) *Cmd
 34
 35	// CommandContext returns a command that can be used to start a process
 36	// attached to the pseudo-terminal.
 37	CommandContext(ctx context.Context, name string, args ...string) *Cmd
 38
 39	// Resize resizes the pseudo-terminal.
 40	Resize(rows, cols int) error
 41
 42	// Control access to the underlying file descriptor in a blocking manner.
 43	// Not implemented on Windows.
 44	Control(f func(fd uintptr)) error
 45}
 46
 47// Cmd is a command that can be started attached to a pseudo-terminal.
 48// This is similar to the API of exec.Cmd. The main difference is that
 49// the command is started attached to a pseudo-terminal.
 50// This is required as we cannot use exec.Cmd directly on Windows due to
 51// limitation of starting a process attached to a pseudo-terminal.
 52// See: https://github.com/golang/go/issues/62708
 53type Cmd struct {
 54	ctx context.Context
 55	pty Pty
 56	sys interface{}
 57
 58	// Path is the path of the command to run.
 59	Path string
 60
 61	// Args holds command line arguments, including the command as Args[0].
 62	Args []string
 63
 64	// Env specifies the environment of the process.
 65	// If Env is nil, the new process uses the current process's environment.
 66	Env []string
 67
 68	// Dir specifies the working directory of the command.
 69	// If Dir is the empty string, the current directory is used.
 70	Dir string
 71
 72	// SysProcAttr holds optional, operating system-specific attributes.
 73	SysProcAttr *syscall.SysProcAttr
 74
 75	// Process is the underlying process, once started.
 76	Process *os.Process
 77
 78	// ProcessState contains information about an exited process.
 79	// If the process was started successfully, Wait or Run will populate this
 80	// field when the command completes.
 81	ProcessState *os.ProcessState
 82
 83	// Cancel is called when the command is canceled.
 84	Cancel func() error
 85}
 86
 87// Start starts the specified command attached to the pseudo-terminal.
 88func (c *Cmd) Start() error {
 89	return c.start()
 90}
 91
 92// Wait waits for the command to exit.
 93func (c *Cmd) Wait() error {
 94	return c.wait()
 95}
 96
 97// Run runs the command and waits for it to complete.
 98func (c *Cmd) Run() error {
 99	if err := c.Start(); err != nil {
100		return err
101	}
102	return c.Wait()
103}