diff options
Diffstat (limited to 'vendor/github.com/creack/pty')
37 files changed, 1128 insertions, 0 deletions
diff --git a/vendor/github.com/creack/pty/.gitignore b/vendor/github.com/creack/pty/.gitignore new file mode 100644 index 000000000..1f0a99f2f --- /dev/null +++ b/vendor/github.com/creack/pty/.gitignore @@ -0,0 +1,4 @@ +[568].out +_go* +_test* +_obj diff --git a/vendor/github.com/creack/pty/Dockerfile.riscv b/vendor/github.com/creack/pty/Dockerfile.riscv new file mode 100644 index 000000000..adfdf82c8 --- /dev/null +++ b/vendor/github.com/creack/pty/Dockerfile.riscv @@ -0,0 +1,14 @@ +FROM golang:1.13 + +# Clone and complie a riscv compatible version of the go compiler. +RUN git clone https://review.gerrithub.io/riscv/riscv-go /riscv-go +# riscvdev branch HEAD as of 2019-06-29. +RUN cd /riscv-go && git checkout 04885fddd096d09d4450726064d06dd107e374bf +ENV PATH=/riscv-go/misc/riscv:/riscv-go/bin:$PATH +RUN cd /riscv-go/src && GOROOT_BOOTSTRAP=$(go env GOROOT) ./make.bash +ENV GOROOT=/riscv-go + +# Make sure we compile. +WORKDIR pty +ADD . . +RUN GOOS=linux GOARCH=riscv go build diff --git a/vendor/github.com/creack/pty/LICENSE b/vendor/github.com/creack/pty/LICENSE new file mode 100644 index 000000000..6b7558b6b --- /dev/null +++ b/vendor/github.com/creack/pty/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2011 Keith Rarick + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall +be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/creack/pty/README.md b/vendor/github.com/creack/pty/README.md new file mode 100644 index 000000000..5275014a7 --- /dev/null +++ b/vendor/github.com/creack/pty/README.md @@ -0,0 +1,100 @@ +# pty + +Pty is a Go package for using unix pseudo-terminals. + +## Install + + go get github.com/creack/pty + +## Example + +### Command + +```go +package main + +import ( + "github.com/creack/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 + +```go +package main + +import ( + "io" + "log" + "os" + "os/exec" + "os/signal" + "syscall" + + "github.com/creack/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) + } +} +``` diff --git a/vendor/github.com/creack/pty/doc.go b/vendor/github.com/creack/pty/doc.go new file mode 100644 index 000000000..190cfbea9 --- /dev/null +++ b/vendor/github.com/creack/pty/doc.go @@ -0,0 +1,16 @@ +// Package pty provides functions for working with Unix terminals. +package pty + +import ( + "errors" + "os" +) + +// ErrUnsupported is returned if a function is not +// available on the current platform. +var ErrUnsupported = errors.New("unsupported") + +// Opens a pty and its corresponding tty. +func Open() (pty, tty *os.File, err error) { + return open() +} diff --git a/vendor/github.com/creack/pty/go.mod b/vendor/github.com/creack/pty/go.mod new file mode 100644 index 000000000..e48decaf4 --- /dev/null +++ b/vendor/github.com/creack/pty/go.mod @@ -0,0 +1,4 @@ +module github.com/creack/pty + +go 1.13 + diff --git a/vendor/github.com/creack/pty/ioctl.go b/vendor/github.com/creack/pty/ioctl.go new file mode 100644 index 000000000..c85cdcd14 --- /dev/null +++ b/vendor/github.com/creack/pty/ioctl.go @@ -0,0 +1,13 @@ +// +build !windows,!solaris + +package pty + +import "syscall" + +func ioctl(fd, cmd, ptr uintptr) error { + _, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr) + if e != 0 { + return e + } + return nil +} diff --git a/vendor/github.com/creack/pty/ioctl_bsd.go b/vendor/github.com/creack/pty/ioctl_bsd.go new file mode 100644 index 000000000..73b12c53c --- /dev/null +++ b/vendor/github.com/creack/pty/ioctl_bsd.go @@ -0,0 +1,39 @@ +// +build darwin dragonfly freebsd netbsd openbsd + +package pty + +// from <sys/ioccom.h> +const ( + _IOC_VOID uintptr = 0x20000000 + _IOC_OUT uintptr = 0x40000000 + _IOC_IN uintptr = 0x80000000 + _IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN + _IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN + + _IOC_PARAM_SHIFT = 13 + _IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1 +) + +func _IOC_PARM_LEN(ioctl uintptr) uintptr { + return (ioctl >> 16) & _IOC_PARAM_MASK +} + +func _IOC(inout uintptr, group byte, ioctl_num uintptr, param_len uintptr) uintptr { + return inout | (param_len&_IOC_PARAM_MASK)<<16 | uintptr(group)<<8 | ioctl_num +} + +func _IO(group byte, ioctl_num uintptr) uintptr { + return _IOC(_IOC_VOID, group, ioctl_num, 0) +} + +func _IOR(group byte, ioctl_num uintptr, param_len uintptr) uintptr { + return _IOC(_IOC_OUT, group, ioctl_num, param_len) +} + +func _IOW(group byte, ioctl_num uintptr, param_len uintptr) uintptr { + return _IOC(_IOC_IN, group, ioctl_num, param_len) +} + +func _IOWR(group byte, ioctl_num uintptr, param_len uintptr) uintptr { + return _IOC(_IOC_IN_OUT, group, ioctl_num, param_len) +} diff --git a/vendor/github.com/creack/pty/ioctl_solaris.go b/vendor/github.com/creack/pty/ioctl_solaris.go new file mode 100644 index 000000000..f63985f34 --- /dev/null +++ b/vendor/github.com/creack/pty/ioctl_solaris.go @@ -0,0 +1,30 @@ +package pty + +import ( + "golang.org/x/sys/unix" + "unsafe" +) + +const ( + // see /usr/include/sys/stropts.h + I_PUSH = uintptr((int32('S')<<8 | 002)) + I_STR = uintptr((int32('S')<<8 | 010)) + I_FIND = uintptr((int32('S')<<8 | 013)) + // see /usr/include/sys/ptms.h + ISPTM = (int32('P') << 8) | 1 + UNLKPT = (int32('P') << 8) | 2 + PTSSTTY = (int32('P') << 8) | 3 + ZONEPT = (int32('P') << 8) | 4 + OWNERPT = (int32('P') << 8) | 5 +) + +type strioctl struct { + ic_cmd int32 + ic_timout int32 + ic_len int32 + ic_dp unsafe.Pointer +} + +func ioctl(fd, cmd, ptr uintptr) error { + return unix.IoctlSetInt(int(fd), uint(cmd), int(ptr)) +} diff --git a/vendor/github.com/creack/pty/mktypes.bash b/vendor/github.com/creack/pty/mktypes.bash new file mode 100644 index 000000000..82ee16721 --- /dev/null +++ b/vendor/github.com/creack/pty/mktypes.bash @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +GOOSARCH="${GOOS}_${GOARCH}" +case "$GOOSARCH" in +_* | *_ | _) + echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2 + exit 1 + ;; +esac + +GODEFS="go tool cgo -godefs" + +$GODEFS types.go |gofmt > ztypes_$GOARCH.go + +case $GOOS in +freebsd|dragonfly|openbsd) + $GODEFS types_$GOOS.go |gofmt > ztypes_$GOOSARCH.go + ;; +esac diff --git a/vendor/github.com/creack/pty/pty_darwin.go b/vendor/github.com/creack/pty/pty_darwin.go new file mode 100644 index 000000000..6344b6b0e --- /dev/null +++ b/vendor/github.com/creack/pty/pty_darwin.go @@ -0,0 +1,65 @@ +package pty + +import ( + "errors" + "os" + "syscall" + "unsafe" +) + +func open() (pty, tty *os.File, err error) { + pFD, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0) + if err != nil { + return nil, nil, err + } + p := os.NewFile(uintptr(pFD), "/dev/ptmx") + // In case of error after this point, make sure we close the ptmx fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + if err := grantpt(p); err != nil { + return nil, nil, err + } + + if err := unlockpt(p); err != nil { + return nil, nil, err + } + + t, err := os.OpenFile(sname, os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + return p, t, nil +} + +func ptsname(f *os.File) (string, error) { + n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME)) + + err := ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0]))) + if err != nil { + return "", err + } + + for i, c := range n { + if c == 0 { + return string(n[:i]), nil + } + } + return "", errors.New("TIOCPTYGNAME string not NUL-terminated") +} + +func grantpt(f *os.File) error { + return ioctl(f.Fd(), syscall.TIOCPTYGRANT, 0) +} + +func unlockpt(f *os.File) error { + return ioctl(f.Fd(), syscall.TIOCPTYUNLK, 0) +} diff --git a/vendor/github.com/creack/pty/pty_dragonfly.go b/vendor/github.com/creack/pty/pty_dragonfly.go new file mode 100644 index 000000000..b7d1f20f2 --- /dev/null +++ b/vendor/github.com/creack/pty/pty_dragonfly.go @@ -0,0 +1,80 @@ +package pty + +import ( + "errors" + "os" + "strings" + "syscall" + "unsafe" +) + +// same code as pty_darwin.go +func open() (pty, tty *os.File, err error) { + p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + // In case of error after this point, make sure we close the ptmx fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + if err := grantpt(p); err != nil { + return nil, nil, err + } + + if err := unlockpt(p); err != nil { + return nil, nil, err + } + + t, err := os.OpenFile(sname, os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + return p, t, nil +} + +func grantpt(f *os.File) error { + _, err := isptmaster(f.Fd()) + return err +} + +func unlockpt(f *os.File) error { + _, err := isptmaster(f.Fd()) + return err +} + +func isptmaster(fd uintptr) (bool, error) { + err := ioctl(fd, syscall.TIOCISPTMASTER, 0) + return err == nil, err +} + +var ( + emptyFiodgnameArg fiodgnameArg + ioctl_FIODNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg)) +) + +func ptsname(f *os.File) (string, error) { + name := make([]byte, _C_SPECNAMELEN) + fa := fiodgnameArg{Name: (*byte)(unsafe.Pointer(&name[0])), Len: _C_SPECNAMELEN, Pad_cgo_0: [4]byte{0, 0, 0, 0}} + + err := ioctl(f.Fd(), ioctl_FIODNAME, uintptr(unsafe.Pointer(&fa))) + if err != nil { + return "", err + } + + for i, c := range name { + if c == 0 { + s := "/dev/" + string(name[:i]) + return strings.Replace(s, "ptm", "pts", -1), nil + } + } + return "", errors.New("TIOCPTYGNAME string not NUL-terminated") +} diff --git a/vendor/github.com/creack/pty/pty_freebsd.go b/vendor/github.com/creack/pty/pty_freebsd.go new file mode 100644 index 000000000..63b6d9133 --- /dev/null +++ b/vendor/github.com/creack/pty/pty_freebsd.go @@ -0,0 +1,78 @@ +package pty + +import ( + "errors" + "os" + "syscall" + "unsafe" +) + +func posixOpenpt(oflag int) (fd int, err error) { + r0, _, e1 := syscall.Syscall(syscall.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0) + fd = int(r0) + if e1 != 0 { + err = e1 + } + return fd, err +} + +func open() (pty, tty *os.File, err error) { + fd, err := posixOpenpt(syscall.O_RDWR | syscall.O_CLOEXEC) + if err != nil { + return nil, nil, err + } + p := os.NewFile(uintptr(fd), "/dev/pts") + // In case of error after this point, make sure we close the pts fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + t, err := os.OpenFile("/dev/"+sname, os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + return p, t, nil +} + +func isptmaster(fd uintptr) (bool, error) { + err := ioctl(fd, syscall.TIOCPTMASTER, 0) + return err == nil, err +} + +var ( + emptyFiodgnameArg fiodgnameArg + ioctlFIODGNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg)) +) + +func ptsname(f *os.File) (string, error) { + master, err := isptmaster(f.Fd()) + if err != nil { + return "", err + } + if !master { + return "", syscall.EINVAL + } + + const n = _C_SPECNAMELEN + 1 + var ( + buf = make([]byte, n) + arg = fiodgnameArg{Len: n, Buf: (*byte)(unsafe.Pointer(&buf[0]))} + ) + if err := ioctl(f.Fd(), ioctlFIODGNAME, uintptr(unsafe.Pointer(&arg))); err != nil { + return "", err + } + + for i, c := range buf { + if c == 0 { + return string(buf[:i]), nil + } + } + return "", errors.New("FIODGNAME string not NUL-terminated") +} diff --git a/vendor/github.com/creack/pty/pty_linux.go b/vendor/github.com/creack/pty/pty_linux.go new file mode 100644 index 000000000..4a833de18 --- /dev/null +++ b/vendor/github.com/creack/pty/pty_linux.go @@ -0,0 +1,51 @@ +package pty + +import ( + "os" + "strconv" + "syscall" + "unsafe" +) + +func open() (pty, tty *os.File, err error) { + p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + // In case of error after this point, make sure we close the ptmx fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + if err := unlockpt(p); err != nil { + return nil, nil, err + } + + t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) + if err != nil { + return nil, nil, err + } + return p, t, nil +} + +func ptsname(f *os.File) (string, error) { + var n _C_uint + err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))) + if err != nil { + return "", err + } + return "/dev/pts/" + strconv.Itoa(int(n)), nil +} + +func unlockpt(f *os.File) error { + var u _C_int + // use TIOCSPTLCK with a pointer to zero to clear the lock + return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))) +} diff --git a/vendor/github.com/creack/pty/pty_openbsd.go b/vendor/github.com/creack/pty/pty_openbsd.go new file mode 100644 index 000000000..a6a35d1e6 --- /dev/null +++ b/vendor/github.com/creack/pty/pty_openbsd.go @@ -0,0 +1,33 @@ +package pty + +import ( + "os" + "syscall" + "unsafe" +) + +func open() (pty, tty *os.File, err error) { + /* + * from ptm(4): + * The PTMGET command allocates a free pseudo terminal, changes its + * ownership to the caller, revokes the access privileges for all previous + * users, opens the file descriptors for the pty and tty devices and + * returns them to the caller in struct ptmget. + */ + + p, err := os.OpenFile("/dev/ptm", os.O_RDWR|syscall.O_CLOEXEC, 0) + if err != nil { + return nil, nil, err + } + defer p.Close() + + var ptm ptmget + if err := ioctl(p.Fd(), uintptr(ioctl_PTMGET), uintptr(unsafe.Pointer(&ptm))); err != nil { + return nil, nil, err + } + + pty = os.NewFile(uintptr(ptm.Cfd), "/dev/ptm") + tty = os.NewFile(uintptr(ptm.Sfd), "/dev/ptm") + + return pty, tty, nil +} diff --git a/vendor/github.com/creack/pty/pty_solaris.go b/vendor/github.com/creack/pty/pty_solaris.go new file mode 100644 index 000000000..09ec1b797 --- /dev/null +++ b/vendor/github.com/creack/pty/pty_solaris.go @@ -0,0 +1,139 @@ +package pty + +/* based on: +http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/pt.c +*/ + +import ( + "errors" + "golang.org/x/sys/unix" + "os" + "strconv" + "syscall" + "unsafe" +) + +const NODEV = ^uint64(0) + +func open() (pty, tty *os.File, err error) { + masterfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|unix.O_NOCTTY, 0) + //masterfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC|unix.O_NOCTTY, 0) + if err != nil { + return nil, nil, err + } + p := os.NewFile(uintptr(masterfd), "/dev/ptmx") + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + err = grantpt(p) + if err != nil { + return nil, nil, err + } + + err = unlockpt(p) + if err != nil { + return nil, nil, err + } + + slavefd, err := syscall.Open(sname, os.O_RDWR|unix.O_NOCTTY, 0) + if err != nil { + return nil, nil, err + } + t := os.NewFile(uintptr(slavefd), sname) + + // pushing terminal driver STREAMS modules as per pts(7) + for _, mod := range([]string{"ptem", "ldterm", "ttcompat"}) { + err = streams_push(t, mod) + if err != nil { + return nil, nil, err + } + } + + return p, t, nil +} + +func minor(x uint64) uint64 { + return x & 0377 +} + +func ptsdev(fd uintptr) uint64 { + istr := strioctl{ISPTM, 0, 0, nil} + err := ioctl(fd, I_STR, uintptr(unsafe.Pointer(&istr))) + if err != nil { + return NODEV + } + var status unix.Stat_t + err = unix.Fstat(int(fd), &status) + if err != nil { + return NODEV + } + return uint64(minor(status.Rdev)) +} + +func ptsname(f *os.File) (string, error) { + dev := ptsdev(f.Fd()) + if dev == NODEV { + return "", errors.New("not a master pty") + } + fn := "/dev/pts/" + strconv.FormatInt(int64(dev), 10) + // access(2) creates the slave device (if the pty exists) + // F_OK == 0 (unistd.h) + err := unix.Access(fn, 0) + if err != nil { + return "", err + } + return fn, nil +} + +type pt_own struct { + pto_ruid int32 + pto_rgid int32 +} + +func grantpt(f *os.File) error { + if ptsdev(f.Fd()) == NODEV { + return errors.New("not a master pty") + } + var pto pt_own + pto.pto_ruid = int32(os.Getuid()) + // XXX should first attempt to get gid of DEFAULT_TTY_GROUP="tty" + pto.pto_rgid = int32(os.Getgid()) + var istr strioctl + istr.ic_cmd = OWNERPT + istr.ic_timout = 0 + istr.ic_len = int32(unsafe.Sizeof(istr)) + istr.ic_dp = unsafe.Pointer(&pto) + err := ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr))) + if err != nil { + return errors.New("access denied") + } + return nil +} + +func unlockpt(f *os.File) error { + istr := strioctl{UNLKPT, 0, 0, nil} + return ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr))) +} + +// push STREAMS modules if not already done so +func streams_push(f *os.File, mod string) error { + var err error + buf := []byte(mod) + // XXX I_FIND is not returning an error when the module + // is already pushed even though truss reports a return + // value of 1. A bug in the Go Solaris syscall interface? + // XXX without this we are at risk of the issue + // https://www.illumos.org/issues/9042 + // but since we are not using libc or XPG4.2, we should not be + // double-pushing modules + + err = ioctl(f.Fd(), I_FIND, uintptr(unsafe.Pointer(&buf[0]))) + |