remove deprecated nomenclature

The words "master" and "slave" in this context are both
harmful and, as a technical matter, confusing and
misleading. It was never my intention to use those terms
in this library, but they snuck in while I wasn't paying
attention.

This change replaces them with "pty" and "tty",
respectively, to be consistent with the other files in
this package and with the device names on BSD platforms.
These terms are not harmful (to the best of my
knowledge) and they're more specific.

In editing the comment in pty_linux.go, this patch also
corrects a factual error. The ioctl argument is not
"zero valued", it is a nonzero pointer to the number 0.
3 files changed
tree: 9ce063e7dd0c473e861ed4088481df992fc2556d
  1. .gitignore
  2. doc.go
  3. go.mod
  4. ioctl.go
  5. ioctl_bsd.go
  6. License
  7. mktypes.bash
  8. pty_darwin.go
  9. pty_dragonfly.go
  10. pty_freebsd.go
  11. pty_linux.go
  12. pty_openbsd.go
  13. pty_unsupported.go
  14. README.md
  15. run.go
  16. types.go
  17. types_dragonfly.go
  18. types_freebsd.go
  19. types_openbsd.go
  20. util.go
  21. ztypes_386.go
  22. ztypes_amd64.go
  23. ztypes_arm.go
  24. ztypes_arm64.go
  25. ztypes_dragonfly_amd64.go
  26. ztypes_freebsd_386.go
  27. ztypes_freebsd_amd64.go
  28. ztypes_freebsd_arm.go
  29. ztypes_mipsx.go
  30. ztypes_openbsd_386.go
  31. ztypes_openbsd_amd64.go
  32. ztypes_ppc64.go
  33. ztypes_ppc64le.go
  34. ztypes_s390x.go
README.md

pty

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

Install

go get github.com/kr/pty

Example

Command

package main

import (
	"github.com/kr/pty"
	"io"
	"os"
	"os/exec"
)

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/kr/pty"
        "golang.org/x/crypto/ssh/terminal"
)

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.

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

        // Copy stdin to the pty and the pty to stdout.
        go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
        _, _ = io.Copy(os.Stdout, ptmx)

        return nil
}

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