diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05a5a0f73..c4bde5b64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,12 +43,23 @@ jobs: restore-keys: | ${{runner.os}}-go- - name: Test code - # we're passing -short so that we skip the integration tests, which will be run in parallel below + # we're passing -short so that we skip the integration tests, which will be run below run: | go test ./... -short integration-tests: - runs-on: ubuntu-latest - name: "Integration Tests" + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + - windows-latest + include: + - os: ubuntu-latest + cache_path: ~/.cache/go-build + - os: windows-latest + cache_path: ~\AppData\Local\go-build + runs-on: ${{matrix.os}} + name: "Integration Tests - ${{matrix.os}}" env: GOFLAGS: -mod=vendor steps: @@ -59,18 +70,20 @@ jobs: with: go-version: 1.18.x - name: Cache build - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: | - ~/.cache/go-build + ${{matrix.cache_path}} ~/go/pkg/mod key: ${{runner.os}}-go-${{hashFiles('**/go.sum')}}-test restore-keys: | ${{runner.os}}-go- - name: Test code - # LONG_WAIT_BEFORE_FAIL means that for a given test assertion, we'll wait longer before failing + env: + # LONG_WAIT_BEFORE_FAIL means that for a given test assertion, we'll wait longer before failing + LONG_WAIT_BEFORE_FAIL: true run: | - LONG_WAIT_BEFORE_FAIL=true go test pkg/integration/clients/*.go + go test ./pkg/integration/clients build: runs-on: ubuntu-latest env: diff --git a/go.mod b/go.mod index 098d19c67..d5b1122fd 100644 --- a/go.mod +++ b/go.mod @@ -73,3 +73,5 @@ require ( golang.org/x/text v0.8.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) + +replace github.com/creack/pty => github.com/photostorm/pty v1.1.19-0.20230324012736-6794a5ba0ba0 diff --git a/go.sum b/go.sum index dd4a8b81e..0b98c043a 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,6 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY= -github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aybabtme/humanlog v0.4.1 h1:D8d9um55rrthJsP8IGSHBcti9lTb/XknmDAX6Zy8tek= @@ -17,9 +15,6 @@ github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI= github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:tuijfIjZyjZaHq9xDUh0tNitwXshJpbLkqMOJv4H3do= github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:po7NpZ/QiTKzBKyrsEAxwnTamCoh8uDk/egRpQ7siIc= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -131,6 +126,8 @@ github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/photostorm/pty v1.1.19-0.20230324012736-6794a5ba0ba0 h1:ahg2J7KgBYMH1KJNvde12jjJZGXwGq0AdRPztBgX2Rc= +github.com/photostorm/pty v1.1.19-0.20230324012736-6794a5ba0ba0/go.mod h1:KO+FcPtyLAiRC0hJwreJVvfwc7vnNz77UxBTIGHdPVk= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -207,6 +204,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220721230656-c6bc011c0c49/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index b429bda27..4c69a4e4e 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -8,6 +8,7 @@ import ( "strings" "sync" + "github.com/creack/pty" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazycore/pkg/boxlayout" appTypes "github.com/jesseduffield/lazygit/pkg/app/types" @@ -75,7 +76,7 @@ type Gui struct { // holds a mapping of view names to ptmx's. This is for rendering command outputs // from within a pty. The point of keeping track of them is so that if we re-size // the window, we can tell the pty it needs to resize accordingly. - viewPtmxMap map[string]*os.File + viewPtmxMap map[string]pty.Pty stopChan chan struct{} // when lazygit is opened outside a git directory we want to open to the most @@ -436,7 +437,7 @@ func NewGui( Updater: updater, statusManager: status.NewStatusManager(), viewBufferManagerMap: map[string]*tasks.ViewBufferManager{}, - viewPtmxMap: map[string]*os.File{}, + viewPtmxMap: map[string]pty.Pty{}, showRecentRepos: showRecentRepos, RepoPathStack: &utils.StringStack{}, RepoStateMap: map[Repo]*GuiRepoState{}, diff --git a/pkg/gui/pty.go b/pkg/gui/pty.go index fe53697c8..5c59ee811 100644 --- a/pkg/gui/pty.go +++ b/pkg/gui/pty.go @@ -5,7 +5,6 @@ package gui import ( "io" - "os" "os/exec" "strings" @@ -57,7 +56,7 @@ func (gui *Gui) newPtyTask(view *gocui.View, cmd *exec.Cmd, prefix string) error manager := gui.getManager(view) - var ptmx *os.File + var ptmx pty.Pty start := func() (*exec.Cmd, io.Reader) { var err error ptmx, err = pty.StartWithSize(cmd, gui.desiredPtySize()) diff --git a/pkg/integration/clients/go_test.go b/pkg/integration/clients/go_test.go index 29d914708..5725bfb49 100644 --- a/pkg/integration/clients/go_test.go +++ b/pkg/integration/clients/go_test.go @@ -1,6 +1,3 @@ -//go:build !windows -// +build !windows - package clients // This file allows you to use `go test` to run integration tests. diff --git a/pkg/integration/components/runner.go b/pkg/integration/components/runner.go index f1f8e3c89..12f5b0681 100644 --- a/pkg/integration/components/runner.go +++ b/pkg/integration/components/runner.go @@ -6,6 +6,7 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "github.com/jesseduffield/lazycore/pkg/utils" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" @@ -198,7 +199,12 @@ func getLazygitCommand(test *IntegrationTest, paths Paths, rootDir string, sandb } func tempLazygitPath() string { - return filepath.Join("/tmp", "lazygit", "test_lazygit") + filename := "test_lazygit" + if runtime.GOOS == "windows" { + filename += ".exe" + } + + return filepath.Join(os.TempDir(), "lazygit", filename) } func findOrCreateDir(path string) { diff --git a/pkg/integration/components/test.go b/pkg/integration/components/test.go index 648c6ed41..0d273f807 100644 --- a/pkg/integration/components/test.go +++ b/pkg/integration/components/test.go @@ -2,6 +2,7 @@ package components import ( "os" + "runtime" "strconv" "strings" @@ -171,6 +172,10 @@ func testNameFromCurrentFilePath() string { } func TestNameFromFilePath(path string) string { + if runtime.GOOS == "windows" { + path = strings.Replace(path, "\\", "/", -1) + } + name := strings.Split(path, "integration/tests/")[1] return name[:len(name)-len(".go")] diff --git a/vendor/github.com/creack/pty/Dockerfile.golang b/vendor/github.com/creack/pty/Dockerfile.golang new file mode 100644 index 000000000..2ee82a3a1 --- /dev/null +++ b/vendor/github.com/creack/pty/Dockerfile.golang @@ -0,0 +1,17 @@ +ARG GOVERSION=1.14 +FROM golang:${GOVERSION} + +# Set base env. +ARG GOOS=linux +ARG GOARCH=amd64 +ENV GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=0 GOFLAGS='-v -ldflags=-s -ldflags=-w' + +# Pre compile the stdlib for 386/arm (32bits). +RUN go build -a std + +# Add the code to the image. +WORKDIR pty +ADD . . + +# Build the lib. +RUN go build diff --git a/vendor/github.com/creack/pty/Dockerfile.riscv b/vendor/github.com/creack/pty/Dockerfile.riscv index adfdf82c8..7a30c94d0 100644 --- a/vendor/github.com/creack/pty/Dockerfile.riscv +++ b/vendor/github.com/creack/pty/Dockerfile.riscv @@ -1,3 +1,4 @@ +# NOTE: Using 1.13 as a base to build the RISCV compiler, the resulting version is based on go1.6. FROM golang:1.13 # Clone and complie a riscv compatible version of the go compiler. @@ -8,7 +9,15 @@ 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. +# Set the base env. +ENV GOOS=linux GOARCH=riscv CGO_ENABLED=0 GOFLAGS='-v -ldflags=-s -ldflags=-w' + +# Pre compile the stdlib. +RUN go build -a std + +# Add the code to the image. WORKDIR pty ADD . . -RUN GOOS=linux GOARCH=riscv go build + +# Build the lib. +RUN go build diff --git a/vendor/github.com/creack/pty/README.md b/vendor/github.com/creack/pty/README.md index 5275014a7..df4bcce0f 100644 --- a/vendor/github.com/creack/pty/README.md +++ b/vendor/github.com/creack/pty/README.md @@ -1,12 +1,18 @@ # pty -Pty is a Go package for using unix pseudo-terminals. +Pty is a Go package for using unix pseudo-terminals and windows ConPty. ## Install - go get github.com/creack/pty +```sh +go get github.com/creack/pty +``` -## Example +## 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](https://docs.microsoft.com/en-us/windows/console/createpseudoconsole#requirements) ### Command @@ -14,10 +20,11 @@ Pty is a Go package for using unix pseudo-terminals. package main import ( - "github.com/creack/pty" "io" "os" "os/exec" + + "github.com/creack/pty" ) func main() { @@ -51,7 +58,7 @@ import ( "syscall" "github.com/creack/pty" - "golang.org/x/crypto/ssh/terminal" + "golang.org/x/term" ) func test() error { @@ -77,15 +84,17 @@ func test() error { } }() ch <- syscall.SIGWINCH // Initial resize. + defer func() { signal.Stop(ch); close(ch) }() // Cleanup signals when done. // Set stdin in raw mode. - oldState, err := terminal.MakeRaw(int(os.Stdin.Fd())) + oldState, err := term.MakeRaw(int(os.Stdin.Fd())) if err != nil { panic(err) } - defer func() { _ = terminal.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort. + 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) diff --git a/vendor/github.com/creack/pty/asm_solaris_amd64.s b/vendor/github.com/creack/pty/asm_solaris_amd64.s new file mode 100644 index 000000000..7fbef8ee6 --- /dev/null +++ b/vendor/github.com/creack/pty/asm_solaris_amd64.s @@ -0,0 +1,18 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc +//+build gc + +#include "textflag.h" + +// +// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go +// + +TEXT ·sysvicall6(SB),NOSPLIT,$0-88 + JMP syscall·sysvicall6(SB) + +TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88 + JMP syscall·rawSysvicall6(SB) diff --git a/vendor/github.com/creack/pty/cmd_windows.go b/vendor/github.com/creack/pty/cmd_windows.go new file mode 100644 index 000000000..d36924f80 --- /dev/null +++ b/vendor/github.com/creack/pty/cmd_windows.go @@ -0,0 +1,356 @@ +//go:build windows +// +build windows + +package pty + +import ( + "bytes" + "errors" + "io" + "os" + "os/exec" + "path/filepath" + "strings" + "syscall" + "unicode/utf16" + "unsafe" + + "golang.org/x/sys/windows" +) + +// copied from os/exec.Cmd for platform compatibility +// we need to use startupInfoEx for pty support, but os/exec.Cmd only have +// support for startupInfo on windows, so we have to rewrite some internal +// logic for windows while keep its behavior compatible with other platforms. + +// windowExecCmd represents an external command being prepared or run. +// +// A cmd cannot be reused after calling its Run, Output or CombinedOutput +// methods. +type windowExecCmd struct { + cmd *exec.Cmd + waitCalled bool + conPty *WindowsPty + attrList *windows.ProcThreadAttributeListContainer +} + +var errProcessNotStarted = errors.New("exec: process has not started yet") + +func (c *windowExecCmd) close() error { + c.attrList.Delete() + _ = c.conPty.Close() + + return nil +} + +func (c *windowExecCmd) Run() error { + err := c.Start() + if err != nil { + return err + } + + return c.Wait() +} + +func (c *windowExecCmd) Wait() error { + if c.cmd.Process == nil { + return errProcessNotStarted + } + + var err error + + if c.waitCalled { + return errors.New("exec: wait was already called") + } + + c.waitCalled = true + c.cmd.ProcessState, err = c.cmd.Process.Wait() + if err != nil { + return err + } + + err = c.close() + if err != nil { + return err + } + + if !c.cmd.ProcessState.Success() { + return &exec.ExitError{ProcessState: c.cmd.ProcessState} + } + + return nil +} + +func (c *windowExecCmd) StdinPipe() (io.WriteCloser, error) { + return nil, ErrUnsupported +} + +func (c *windowExecCmd) StdoutPipe() (io.ReadCloser, error) { + return nil, ErrUnsupported +} + +func (c *windowExecCmd) StderrPipe() (io.ReadCloser, error) { + return nil, ErrUnsupported +} + +func (c *windowExecCmd) Output() ([]byte, error) { + if c.cmd.Stdout != nil { + return nil, errors.New("exec: Stdout already set") + } + + var stdout bytes.Buffer + c.cmd.Stdout = &stdout + + err := c.Run() + return stdout.Bytes(), err +} + +func (c *windowExecCmd) CombinedOutput() ([]byte, error) { + if c.cmd.Stdout != nil { + return nil, errors.New("exec: Stdout already set") + } + if c.cmd.Stderr != nil { + return nil, errors.New("exec: Stderr already set") + } + var b bytes.Buffer + c.cmd.Stdout = &b + c.cmd.Stderr = &b + err := c.Run() + return b.Bytes(), err +} + +func (c *windowExecCmd) argv() []string { + if len(c.cmd.Args) > 0 { + return c.cmd.Args + } + + return []string{c.cmd.Path} +} + +// +// Helpers for working with Windows. These are exact copies of the same utilities found in the go stdlib. +// + +func lookExtensions(path, dir string) (string, error) { + if filepath.Base(path) == path { + path = filepath.Join(".", path) + } + + if dir == "" { + return exec.LookPath(path) + } + + if filepath.VolumeName(path) != "" { + return exec.LookPath(path) + } + + if len(path) > 1 && os.IsPathSeparator(path[0]) { + return exec.LookPath(path) + } + + dirandpath := filepath.Join(dir, path) + + // We assume that LookPath will only add file extension. + lp, err := exec.LookPath(dirandpath) + if err != nil { + return "", err + } + + ext := strings.TrimPrefix(lp, dirandpath) + + return path + ext, nil +} + +func dedupEnvCase(caseInsensitive bool, env []string) []string { + // Construct the output in reverse order, to preserve the + // last occurrence of each key. + out := make([]string, 0, len(env)) + saw := make(map[string]bool, len(env)) + for n := len(env); n > 0; n-- { + kv := env[n-1] + + i := strings.Index(kv, "=") + if i == 0 { + // We observe in practice keys with a single leading "=" on Windows. + // TODO(#49886): Should we consume only the first leading "=" as part + // of the key, or parse through arbitrarily many of them until a non-"="? + i = strings.Index(kv[1:], "=") + 1 + } + if i < 0 { + if kv != "" { + // The entry is not of the form "key=value" (as it is required to be). + // Leave it as-is for now. + // TODO(#52436): should we strip or reject these bogus entries? + out = append(out, kv) + } + continue + } + k := kv[:i] + if caseInsensitive { + k = strings.ToLower(k) + } + if saw[k] { + continue + } + + saw[k] = true + out = append(out, kv) + } + + // Now reverse the slice to restore the original order. + for i := 0; i < len(out)/2; i++ { + j := len(out) - i - 1 + out[i], out[j] = out[j], out[i] + } + + return out +} + +func addCriticalEnv(env []string) []string { + for _, kv := range env { + eq := strings.Index(kv, "=") + if eq < 0 { + continue + } + k := kv[:eq] + if strings.EqualFold(k, "SYSTEMROOT") { + // We already have it. + return env + } + } + + return append(env, "SYSTEMROOT="+os.Getenv("SYSTEMROOT")) +} + +func execEnvDefault(sys *syscall.SysProcAttr) (env []string, err error) { + if sys == nil || sys.Token == 0 { + return syscall.Environ(), nil + } + + var block *uint16 + err = windows.CreateEnvironmentBlock(&block, windows.Token(sys.Token), false) + if err != nil { + return nil, err + } + + defer windows.DestroyEnvironmentBlock(block) + blockp := uintptr(unsafe.Pointer(block)) + + for { + + // find NUL terminator + end := unsafe.Pointer(blockp) + for *(*uint16)(end) != 0 { + end = unsafe.Pointer(uintptr(end) + 2) + } + + n := (uintptr(end) - uintptr(unsafe.Pointer(blockp))) / 2 + if n == 0 { + // environment block ends with empty string + break + } + + entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:n:n] + env = append(env, string(utf16.Decode(entry))) + blockp += 2 * (uintptr(len(entry)) + 1) + } + return +} + +func createEnvBlock(envv []string) *uint16 { + if len(envv) == 0 { + return &utf16.Encode([]rune("\x00\x00"))[0] + } + length := 0 + for _, s := range envv { + length += len(s) + 1 + } + length += 1 + + b := make([]byte, length) + i := 0 + for _, s := range envv { + l := len(s) + copy(b[i:i+l], []byte(s)) + copy(b[i+l:i+l+1], []byte{0}) + i = i + l + 1 + } + copy(b[i:i+1], []byte{0}) + + return &utf16.Encode([]rune(string(b)))[0] +} + +func makeCmdLine(args []string) string { + var s string + for _, v := range args { + if s != "" { + s += " " + } + s += windows.EscapeArg(v) + } + return s +} + +func isSlash(c uint8) bool { + return c == '\\' || c == '/' +} + +func normalizeDir(dir string) (name string, err error) { + ndir, err := syscall.FullPath(dir) + if err != nil { + return "", err + } + if len(ndir) > 2 && isSlash(ndir[0]) && isSlash(ndir[1]) { + // dir cannot have \\server\share\path form + return "", syscall.EINVAL + } + return ndir, nil +} + +func volToUpper(ch int) int { + if 'a' <= ch && ch <= 'z' { + ch += 'A' - 'a' + } + return ch +} + +func joinExeDirAndFName(dir, p string) (name string, err error) { + if len(p) == 0 { + return "", syscall.EINVAL + } + if len(p) > 2 && isSlash(p[0]) && isSlash(p[1]) { + // \\server\share\path form + return p, nil + } + if len(p) > 1 && p[1] == ':' { + // has drive letter + if len(p) == 2 { + return "", syscall.EINVAL + } + if isSlash(p[2]) { + return p, nil + } else { + d, err := normalizeDir(dir) + if err != nil { + return "", err + } + if volToUpper(int(p[0])) == volToUpper(int(d[0])) { + return syscall.FullPath(d + "\\" + p[2:]) + } else { + return syscall.FullPath(p) + } + } + } else { + // no drive letter + d, err := normalizeDir(dir) + if err != nil { + return "", err + } + + if isSlash(p[0]) { + return windows.FullPath(d[:2] + p) + } else { + return windows.FullPath(d + "\\" + p) + } + } +} diff --git a/vendor/github.com/creack/pty/doc.go b/vendor/github.com/creack/pty/doc.go index 190cfbea9..033d43add 100644 --- a/vendor/github.com/creack/pty/doc.go +++ b/vendor/github.com/creack/pty/doc.go @@ -3,14 +3,44 @@ package pty import ( "errors" - "os" + "io" ) // 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) { +// Open a pty and its corresponding tty. +func Open() (Pty, Tty, error) { return open() } + +type FdHolder interface { + Fd() uintptr +} + +// 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 +type Pty interface { + // FdHolder 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 +} + +// 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 Tty interface { + // FdHolder Fd only intended for manual InheritSize from Pty + FdHolder + + Name() string + + io.ReadWriteCloser +} diff --git a/vendor/github.com/creack/pty/ioctl.go b/vendor/github.com/creack/pty/ioctl.go index c85cdcd14..3cabedd96 100644 --- a/vendor/github.com/creack/pty/ioctl.go +++ b/vendor/github.com/creack/pty/ioctl.go @@ -1,9 +1,15 @@ -// +build !windows,!solaris +//go:build !windows && !solaris && !aix +// +build !windows,!solaris,!aix package pty import "syscall" +const ( + TIOCGWINSZ = syscall.TIOCGWINSZ + TIOCSWINSZ = syscall.TIOCSWINSZ +) + func ioctl(fd, cmd, ptr uintptr) error { _, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr) if e != 0 { diff --git a/vendor/github.com/creack/pty/ioctl_bsd.go b/vendor/github.com/creack/pty/ioctl_bsd.go index 73b12c53c..db3bf845b 100644 --- a/vendor/github.com/creack/pty/ioctl_bsd.go +++ b/vendor/github.com/creack/pty/ioctl_bsd.go @@ -1,3 +1,4 @@ +//go:build darwin || dragonfly || freebsd || netbsd || openbsd // +build darwin dragonfly freebsd netbsd openbsd package pty diff --git a/vendor/github.com/creack/pty/ioctl_solaris.go b/vendor/github.com/creack/pty/ioctl_solaris.go index f63985f34..bff22dad0 100644 --- a/vendor/github.com/creack/pty/ioctl_solaris.go +++ b/vendor/github.com/creack/pty/ioctl_solaris.go @@ -1,30 +1,48 @@ +//go:build solaris +// +build solaris + package pty import ( - "golang.org/x/sys/unix" + "syscall" "unsafe" ) +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" +//go:linkname procioctl libc_ioctl +var procioctl uintptr + 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)) + 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 + + // see /usr/include/sys/termios.h + TIOCSWINSZ = (uint32('T') << 8) | 103 + TIOCGWINSZ = (uint32('T') << 8) | 104 ) type strioctl struct { - ic_cmd int32 - ic_timout int32 - ic_len int32 - ic_dp unsafe.Pointer + icCmd int32 + icTimeout int32 + icLen int32 + icDP unsafe.Pointer } +// Defined in asm_solaris_amd64.s. +func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) + func ioctl(fd, cmd, ptr uintptr) error { - return unix.IoctlSetInt(int(fd), uint(cmd), int(ptr)) + if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, fd, cmd, ptr, 0, 0, 0); errno != 0 { + return errno + } + return nil } diff --git a/vendor/github.com/creack/pty/ioctl_unsupported.go b/vendor/github.com/creack/pty/ioctl_unsupported.go new file mode 100644 index 000000000..2449a27ee --- /dev/null +++ b/vendor/github.com/creack/pty/ioctl_unsupported.go @@ -0,0 +1,13 @@ +//go:build aix +// +build aix + +package pty + +const ( + TIOCGWINSZ = 0 + TIOCSWINSZ = 0 +) + +func ioctl(fd, cmd, ptr uintptr) error { + return ErrUnsupported +} diff --git a/vendor/github.com/creack/pty/mktypes.bash b/vendor/github.com/creack/pty/mktypes.bash index 82ee16721..7f71bda6a 100644 --- a/vendor/github.com/creack/pty/mktypes.bash +++ b/vendor/github.com/creack/pty/mktypes.bash @@ -13,7 +13,7 @@ GODEFS="go tool cgo -godefs" $GODEFS types.go |gofmt > ztypes_$GOARCH.go case $GOOS in -freebsd|dragonfly|openbsd) +freebsd|dragonfly|netbsd|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 index 6344b6b0e..9bdd71d08 100644 --- a/vendor/github.com/creack/pty/pty_darwin.go +++ b/vendor/github.com/creack/pty/pty_darwin.go @@ -1,3 +1,6 @@ +//go:build darwin +// +build darwin + package pty import ( @@ -33,7 +36,7 @@ func open() (pty, tty *os.File, err error) { return nil, nil, err } - t, err := os.OpenFile(sname, os.O_RDWR, 0) + t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) if err != nil { return nil, nil, err } diff --git a/vendor/github.com/creack/pty/pty_dragonfly.go b/vendor/github.com/creack/pty/pty_dragonfly.go index b7d1f20f2..aa916aadf 100644 --- a/vendor/github.com/creack/pty/pty_dragonfly.go +++ b/vendor/github.com/creack/pty/pty_dragonfly.go @@ -1,3 +1,6 @@ +//go:build dragonfly +// +build dragonfly + package pty import ( diff --git a/vendor/github.com/creack/pty/pty_freebsd.go b/vendor/github.com/creack/pty/pty_freebsd.go index 63b6d9133..bcd3b6f90 100644 --- a/vendor/github.com/creack/pty/pty_freebsd.go +++ b/vendor/github.com/creack/pty/pty_freebsd.go @@ -1,3 +1,6 @@ +//go:build freebsd +// +build freebsd + package pty import ( diff --git a/vendor/github.com/creack/pty/pty_linux.go b/vendor/github.com/creack/pty/pty_linux.go index 4a833de18..a3b368f56 100644 --- a/vendor/github.com/creack/pty/pty_linux.go +++ b/vendor/github.com/creack/pty/pty_linux.go @@ -1,3 +1,6 @@ +//go:build linux +// +build linux + package pty import ( @@ -28,7 +31,7 @@ func open() (pty, tty *os.File, err error) { return nil, nil, err } - t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) + t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) //nolint:gosec // Expected Open from a variable. if err != nil { return nil, nil, err } @@ -37,7 +40,7 @@ func open() (pty, tty *os.File, err error) { func ptsname(f *os.File) (string, error) { var n _C_uint - err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))) + err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))) //nolint:gosec // Expected unsafe pointer for Syscall call. if err != nil { return "", err } @@ -47,5 +50,5 @@ func ptsname(f *os.File) (string, error) { 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))) + return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))) //nolint:gosec // Expected unsafe pointer for Syscall call. } diff --git a/vendor/github.com/creack/pty/pty_netbsd.go b/vendor/github.com/creack/pty/pty_netbsd.go new file mode 100644 index 000000000..2b20d944c --- /dev/null +++ b/vendor/github.com/creack/pty/pty_netbsd.go @@ -0,0 +1,69 @@ +//go:build netbsd +// +build netbsd + +package pty + +import ( + "errors" + "os" + "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 := grantpt(p); err != nil { + return nil, nil, err + } + + // In NetBSD unlockpt() does nothing, so it isn't called here. + + 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) { + /* + * from ptsname(3): The ptsname() function is equivalent to: + * struct ptmget pm; + * ioctl(fd, TIOCPTSNAME, &pm) == -1 ? NULL : pm.sn; + */ + var ptm ptmget + if err := ioctl(f.Fd(), uintptr(ioctl_TIOCPTSNAME), uintptr(unsafe.Pointer(&ptm))); err != nil { + return "", err + } + name := make([]byte, len(ptm.Sn)) + for i, c := range ptm.Sn { + name[i] = byte(c) + if c == 0 { + return string(name[:i]), nil + } + } + return "", errors.New("TIOCPTSNAME string not NUL-terminated") +} + +func grantpt(f *os.File) error { + /* + * from grantpt(3): Calling grantpt() is equivalent to: + * ioctl(fd, TIOCGRANTPT, 0); + */ + return ioctl(f.Fd(), uintptr(ioctl_TIOCGRANTPT), 0) +} diff --git a/vendor/github.com/creack/pty/pty_openbsd.go b/vendor/github.com/creack/pty/pty_openbsd.go index a6a35d1e6..aada5e3f6 100644 --- a/vendor/github.com/creack/pty/pty_openbsd.go +++ b/vendor/github.com/creack/pty/pty_openbsd.go @@ -1,3 +1,6 @@ +//go:build openbsd +// +build openbsd + package pty import ( @@ -6,6 +9,17 @@ import ( "unsafe" ) +func cInt8ToString(in []int8) string { + var s []byte + for _, v := range in { + if v == 0 { + break + } + s = append(s, byte(v)) + } + return string(s) +} + func open() (pty, tty *os.File, err error) { /* * from ptm(4): @@ -26,8 +40,8 @@ func open() (pty, tty *os.File, err error) { return nil, nil, err } - pty = os.NewFile(uintptr(ptm.Cfd), "/dev/ptm") - tty = os.NewFile(uintptr(ptm.Sfd), "/dev/ptm") + pty = os.NewFile(uintptr(ptm.Cfd), cInt8ToString(ptm.Cn[:])) + tty = os.NewFile(uintptr(ptm.Sfd), cInt8ToString(ptm.Sn[:])) return pty, tty, nil } diff --git a/vendor/github.com/creack/pty/pty_solaris.go b/vendor/github.com/creack/pty/pty_solaris.go index 09ec1b797..37f933e60 100644 --- a/vendor/github.com/creack/pty/pty_solaris.go +++ b/vendor/github.com/creack/pty/pty_solaris.go @@ -1,3 +1,6 @@ +//go:build solaris +// +build solaris + package pty /* based on: @@ -6,122 +9,134 @@ 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) + ptmxfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY, 0) if err != nil { return nil, nil, err } - p := os.NewFile(uintptr(masterfd), "/dev/ptmx") + p := os.NewFile(uintptr(ptmxfd), "/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 } - err = grantpt(p) - if err != nil { + if err := grantpt(p); err != nil { return nil, nil, err } - err = unlockpt(p) - if err != nil { + if err := unlockpt(p); err != nil { return nil, nil, err } - slavefd, err := syscall.Open(sname, os.O_RDWR|unix.O_NOCTTY, 0) + ptsfd, err := syscall.Open(sname, os.O_RDWR|syscall.O_NOCTTY, 0) if err != nil { return nil, nil, err } - t := os.NewFile(uintptr(slavefd), sname) + t := os.NewFile(uintptr(ptsfd), sname) + + // In case of error after this point, make sure we close the pts fd. + defer func() { + if err != nil { + _ = t.Close() // Best effort. + } + }() // pushing terminal driver STREAMS modules as per pts(7) - for _, mod := range([]string{"ptem", "ldterm", "ttcompat"}) { - err = streams_push(t, mod) - if err != nil { + for _, mod := range []string{"ptem", "ldterm", "ttcompat"} { + if err := streamsPush(t, mod); 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") + dev, err := ptsdev(f.Fd()) + if err != nil { + return "", err } 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 { + + if err := syscall.Access(fn, 0); err != nil { return "", err } return fn, nil } -type pt_own struct { - pto_ruid int32 - pto_rgid int32 +func unlockpt(f *os.File) error { + istr := strioctl{ + icCmd: UNLKPT, + icTimeout: 0, + icLen: 0, + icDP: nil, + } + return ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr))) +} + +func minor(x uint64) uint64 { return x & 0377 } + +func ptsdev(fd uintptr) (uint64, error) { + istr := strioctl{ + icCmd: ISPTM, + icTimeout: 0, + icLen: 0, + icDP: nil, + } + + if err := ioctl(fd, I_STR, uintptr(unsafe.Pointer(&istr))); err != nil { + return 0, err + } + var status syscall.Stat_t + if err := syscall.Fstat(int(fd), &status); err != nil { + return 0, err + } + return uint64(minor(status.Rdev)), nil +} + +type ptOwn struct { + rUID int32 + rGID int32 } func grantpt(f *os.File) error { - if ptsdev(f.Fd()) == NODEV { - return errors.New("not a master pty") + if _, err := ptsdev(f.Fd()); err != nil { + return err } - 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 { + pto := ptOwn{ + rUID: int32(os.Getuid()), + // XXX should first attempt to get gid of DEFAULT_TTY_GROUP="tty" + rGID: int32(os.Getgid()), + } + istr := strioctl{ + icCmd: OWNERPT, + icTimeout: 0, + icLen: int32(unsafe.Sizeof(strioctl{})), + icDP: unsafe.Pointer(&pto), + } + if err := ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr))); 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 +// streamsPush pushes STREAMS modules if not already done so. +func streamsPush(f *os.File, mod string) 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? @@ -129,11 +144,9 @@ func streams_push(f *os.File, mod string) error { // 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]))) - if err != nil { + + if err := ioctl(f.Fd(), I_FIND, uintptr(unsafe.Pointer(&buf[0]))); err != nil { return nil } - err = ioctl(f.Fd(), I_PUSH, uintptr(unsafe.Pointer(&buf[0]))) - return err + return ioctl(f.Fd(), I_PUSH, uintptr(unsafe.Pointer(&buf[0]))) } diff --git a/vendor/github.com/creack/pty/pty_unsupported.go b/vendor/github.com/creack/pty/pty_unsupported.go index ceb425b19..c0ef327d3 100644 --- a/vendor/github.com/creack/pty/pty_unsupported.go +++ b/vendor/github.com/creack/pty/pty_unsupported.go @@ -1,4 +1,5 @@ -// +build !linux,!darwin,!freebsd,!dragonfly,!openbsd,!solaris +//go:build !linux && !darwin && !freebsd && !dragonfly && !netbsd && !openbsd && !solaris && !windows +// +build !linux,!darwin,!freebsd,!dragonfly,!netbsd,!openbsd,!solaris,!windows package pty diff --git a/vendor/github.com/creack/pty/pty_windows.go b/vendor/github.com/creack/pty/pty_windows.go new file mode 100644 index 000000000..aa8eb0be4 --- /dev/null +++ b/vendor/github.com/creack/pty/pty_windows.go @@ -0,0 +1,187 @@ +//go:build windows +// +build windows + +package pty + +import ( + "fmt" + "os" + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +const ( + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x20016 +) + +type WindowsPty struct { + handle windows.Handle + r, w *os.File +} + +type WindowsTty struct { + handle windows.Handle + r, w *os.File +} + +var ( + // NOTE(security): as noted by the comment of syscall.NewLazyDLL and syscall.LoadDLL + // user need to call internal/syscall/windows/sysdll.Add("kernel32.dll") to make sure + // the kernel32.dll is loaded from windows system path + // + // ref: https://pkg.go.dev/syscall@go1.13?GOOS=windows#LoadDLL + kernel32DLL = windows.NewLazyDLL("kernel32.dll") + + // https://docs.microsoft.com/en-us/windows/console/createpseudoconsole + createPseudoConsole = kernel32DLL.NewProc("CreatePseudoConsole") + closePseudoConsole = kernel32DLL.NewProc("ClosePseudoConsole") + + resizePseudoConsole = kernel32DLL.NewProc("ResizePseudoConsole") + getConsoleScreenBufferInfo = kernel32DLL.NewProc("GetConsoleScreenBufferInfo") +) + +func open() (_ Pty, _ Tty, err error) { + pr, consoleW, err := os.Pipe() + if err != nil { + return nil, nil, err + } + + consoleR, pw, err := os.Pipe() + if err != nil { + _ = consoleW.Close() + _ = pr.Close() + return nil, nil, err + } + + var consoleHandle windows.Handle + + err = procCreatePseudoConsole(windows.Handle(consoleR.Fd()), windows.Handle(consoleW.Fd()), + 0, &consoleHandle) + if err != nil { + _ = consoleW.Close() + _ = pr.Close() + _ = pw.Close() + _ = consoleR.Close() + return nil, nil, err + } + + // These pipes can be closed here without any worry + err = consoleW.Close() + if err != nil { + return nil, nil, fmt.Errorf("failed to close pseudo console handle: %w", err) + } + + err = consoleR.Close() + if err != nil { + return nil, nil, fmt.Errorf("failed to close pseudo console handle: %w", err) + } + + return &WindowsPty{ + handle: consoleHandle, + r: pr, + w: pw, + }, &WindowsTty{ + handle: consoleHandle, + r: consoleR, + w: consoleW, + }, nil +} + +func (p *WindowsPty) Name() string { + return p.r.Name() +} + +func (p *WindowsPty) Fd() uintptr { + return uintptr(p.handle) +} + +func (p *WindowsPty) Read(data []byte) (int, error) { + return p.r.Read(data) +} + +func (p *WindowsPty) Write(data []byte) (int, error) { + return p.w.Write(data) +} + +func (p *WindowsPty) WriteString(s string) (int, error) { + return p.w.WriteString(s) +} + +func (p *WindowsPty) UpdateProcThreadAttribute(attrList *windows.ProcThreadAttributeListContainer) error { + var err error + + if err = attrList.Update( + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, + unsafe.Pointer(p.handle), + unsafe.Sizeof(p.handle), + ); err != nil { + return fmt.Errorf("failed to update proc thread attributes for pseudo console: %w", err) + } + + return nil +} + +func (p *WindowsPty) Close() error { + _ = p.r.Close() + _ = p.w.Close() + + err := closePseudoConsole.Find() + if err != nil { + return err + } + + _, _, err = closePseudoConsole.Call(uintptr(p.handle)) + return err +} + +func (t *WindowsTty) Name() string { + return t.r.Name() +} + +func (t *WindowsTty) Fd() uintptr { + return uintptr(t.handle) +} + +func (t *WindowsTty) Read(p []byte) (int, error) { + return t.r.Read(p) +} + +func (t *WindowsTty) Write(p []byte) (int, error) { + return t.w.Write(p) +} + +func (t *WindowsTty) Close() error { + _ = t.r.Close() + return t.w.Close() +} + +func procCreatePseudoConsole(hInput windows.Handle, hOutput windows.Handle, dwFlags uint32, consoleHandle *windows.Handle) error { + var r0 uintptr + var err error + + err = createPseudoConsole.Find() + if err != nil { + return err + } + + r0, _, err = createPseudoConsole.Call( + (windowsCoord{X: 80, Y: 30}).Pack(), // size: default 80x30 window + uintptr(hInput), // console input + uintptr(hOutput), // console output + uintptr(dwFlags), // console flags, currently only PSEUDOCONSOLE_INHERIT_CURSOR supported + uintptr(unsafe.Pointer(consoleHandle)), // console handler value return + ) + + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + + // S_OK: 0 + return syscall.Errno(r0) + } + + return nil +} diff --git a/vendor/github.com/creack/pty/run.go b/vendor/github.com/creack/pty/run.go index b07942514..0b97b94d2 100644 --- a/vendor/github.com/creack/pty/run.go +++ b/vendor/github.com/creack/pty/run.go @@ -1,11 +1,7 @@ -// +build !windows - package pty import ( - "os" "os/exec" - "syscall" ) // Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, @@ -13,62 +9,6 @@ import ( // corresponding pty. // // Starts the process in a new session and sets the controlling terminal. -func Start(c *exec.Cmd) (pty *os.File, err error) { - return StartWithSize(c, nil) -} - -// 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. -func StartWithSize(c *exec.Cmd, sz *Winsize) (pty *os.File, err error) { - if c.SysProcAttr == nil { - c.SysProcAttr = &syscall.SysProcAttr{} - } - c.SysProcAttr.Setsid = true - c.SysProcAttr.Setctty = true - return StartWithAttrs(c, sz, c.SysProcAttr) -} - -// StartWithAttrs 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 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 StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (pty *os.File, err error) { - pty, tty, err := Open() - if err != nil { - return nil, err - } - defer tty.Close() - - if sz != nil { - if err := Setsize(pty, sz); err != nil { - pty.Close() - return nil, err - } - } - if c.Stdout == nil { - c.Stdout = tty - } - if c.Stderr == nil { - c.Stderr = tty - } - if c.Stdin == nil { - c.Stdin = tty - } - - c.SysProcAttr = attrs - - if err := c.Start(); err != nil { - _ = pty.Close() - return nil, err - } - return pty, err +func Start(cmd *exec.Cmd) (Pty, error) { + return StartWithSize(cmd, nil) } diff --git a/vendor/github.com/creack/pty/run_unix.go b/vendor/github.com/creack/pty/run_unix.go new file mode 100644 index 000000000..6d432919f --- /dev/null +++ b/vendor/github.com/creack/pty/run_unix.go @@ -0,0 +1,69 @@ +//go:build !windows +// +build !windows + +package pty + +import ( + "os/exec" + "syscall" +) + +// 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. +func StartWithSize(c *exec.Cmd, sz *Winsize) (Pty, error) { + if c.SysProcAttr == nil { + c.SysProcAttr = &syscall.SysProcAttr{} + } + c.SysProcAttr.Setsid = true + c.SysProcAttr.Setctty = true + return StartWithAttrs(c, sz, c.SysProcAttr) +} + +// 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 StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (Pty, error) { + pty, tty, err := open() + if err != nil { + return nil, err + } + defer func() { + // always close tty fds since it's being used in another process + // but pty is kept to resize tty + _ = tty.Close() + }() + + if sz != nil { + if err := Setsize(pty, sz); err != nil { + _ = pty.Close() + return nil, err + } + } + if c.Stdout == nil { + c.Stdout = tty + } + if c.Stderr == nil { + c.Stderr = tty + } + if c.Stdin == nil { + c.Stdin = tty + } + + c.SysProcAttr = attrs + + if err := c.Start(); err != nil { + _ = pty.Close() + return nil, err + } + return pty, err +} diff --git a/vendor/github.com/creack/pty/run_windows.go b/vendor/github.com/creack/pty/run_windows.go new file mode 100644 index 000000000..8b2a511a6 --- /dev/null +++ b/vendor/github.com/creack/pty/run_windows.go @@ -0,0 +1,230 @@ +//go:build windows +// +build windows + +package pty + +import ( + "errors" + "fmt" + "os" + "os/exec" + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +// 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. +func StartWithSize(c *exec.Cmd, sz *Winsize) (Pty, error) { + return StartWithAttrs(c, sz, c.SysProcAttr) +} + +// 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 StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (Pty, error) { + pty, _, err := open() + if err != nil { + return nil, err + } + + defer func() { + // unlike unix command exec, do not close tty unless error happened + if err != nil { + _ = pty.Close() + } + }() + + if sz != nil { + if err = Setsize(pty, sz); err != nil { + return nil, err + } + } + + // unlike unix command exec, do not set stdin/stdout/stderr + + c.SysProcAttr = attrs + + // do not use os/exec.Start since we need to append console handler to startup info + + w := windowExecCmd{ + cmd: c, + waitCalled: false, + conPty: pty.(*WindowsPty), + } + + err = w.Start() + if err != nil { + return nil, err + } + + return pty, err +} + +// Start the specified command but does not wait for it to complete. +// +// If Start returns successfully, the c.Process field will be set. +// +// The Wait method will return the exit code and release associated resources +// once the command exits. +func (c *windowExecCmd) Start() error { + if c.cmd.Process != nil { + return errors.New("exec: already started") + } + + var argv0 = c.cmd.Path + var argv0p *uint16 + var argvp *uint16 + var dirp *uint16 + var err error + + sys := c.cmd.SysProcAttr + if sys == nil { + sys = &syscall.SysProcAttr{} + } + + if c.cmd.Env == nil { + c.cmd.Env, err = execEnvDefault(sys) + if err != nil { + return err + } + } + + var lp string + + lp, err = lookExtensions(c.cmd.Path, c.cmd.Dir) + if err != nil { + return err + } + + c.cmd.Path = lp + + if len(c.cmd.Dir) != 0 { + // Windows CreateProcess looks for argv0 relative to the current + // directory, and, only once the new process is started, it does + // Chdir(attr.Dir). We are adjusting for that difference here by + // making argv0 absolute. + + argv0, err = joinExeDirAndFName(c.cmd.Dir, c.cmd.Path) + if err != nil { + return err + } + } + + argv0p, err = syscall.UTF16PtrFromString(argv0) + if err != nil { + return err + } + + var cmdline string + + // Windows CreateProcess takes the command line as a single string: + // use attr.CmdLine if set, else build the command line by escaping + // and joining each argument with spaces + if sys.CmdLine != "" { + cmdline = sys.CmdLine + } else { + cmdline = makeCmdLine(c.argv()) + } + + if len(cmdline) != 0 { + argvp, err = windows.UTF16PtrFromString(cmdline) + if err != nil { + return err + } + } + + if len(c.cmd.Dir) != 0 { + dirp, err = windows.UTF16PtrFromString(c.cmd.Dir) + if err != nil { + return err + } + } + + // Acquire the fork lock so that no other threads + // create new fds that are not yet close-on-exec + // before we fork. + syscall.ForkLock.Lock() + defer syscall.ForkLock.Unlock() + + siEx := new(windows.StartupInfoEx) + siEx.Flags = windows.STARTF_USESTDHANDLES + + if sys.HideWindow { + siEx.Flags |= syscall.STARTF_USESHOWWINDOW + siEx.ShowWindow = syscall.SW_HIDE + } + + pi := new(windows.ProcessInformation) + + // Need EXTENDED_STARTUPINFO_PRESENT as we're making use of the attribute list field. + flags := sys.CreationFlags | uint32(windows.CREATE_UNICODE_ENVIRONMENT) | windows.EXTENDED_STARTUPINFO_PRESENT + + c.attrList, err = windows.NewProcThreadAttributeList(1) + if err != nil { + return fmt.Errorf("failed to initialize process thread attribute list: %w", err) + } + + if c.conPty != nil { + if err = c.conPty.UpdateProcThreadAttribute(c.attrList); err != nil { + return err + } + } + + siEx.ProcThreadAttributeList = c.attrList.List() + siEx.Cb = uint32(unsafe.Sizeof(*siEx)) + + if sys.Token != 0 { + err = windows.CreateProcessAsUser( + windows.Token(sys.Token), + argv0p, + argvp, + nil, + nil, + false, + flags, + createEnvBlock(addCriticalEnv(dedupEnvCase(true, c.cmd.Env))), + dirp, + &siEx.StartupInfo, + pi, + ) + } else { + err = windows.CreateProcess( + argv0p, + argvp, + nil, + nil, + false, + flags, + createEnvBlock(addCriticalEnv(dedupEnvCase(true, c.cmd.Env))), + dirp, + &siEx.StartupInfo, + pi, + ) + } + if err != nil { + return err + } + + defer func() { + _ = windows.CloseHandle(pi.Thread) + }() + + c.cmd.Process, err = os.FindProcess(int(pi.ProcessId)) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/creack/pty/test_crosscompile.sh b/vendor/github.com/creack/pty/test_crosscompile.sh index c4b9e3734..5bf80f9bb 100644 --- a/vendor/github.com/creack/pty/test_crosscompile.sh +++ b/vendor/github.com/creack/pty/test_crosscompile.sh @@ -4,47 +4,59 @@ # Does not actually test the logic, just the compilation so we make sure we don't break code depending on the lib. echo2() { - echo $@ >&2 + echo $@ >&2 } trap end 0 end() { - [ "$?" = 0 ] && echo2 "Pass." || (echo2 "Fail."; exit 1) + [ "$?" = 0 ] && echo2 "Pass." || (echo2 "Fail."; exit 1) } cross() { - os=$1 - shift - echo2 "Build for $os." - for arch in $@; do - echo2 " - $os/$arch" - GOOS=$os GOARCH=$arch go build - done - echo2 + os=$1 + shift + echo2 "Build for $os." + for arch in $@; do + echo2 " - $os/$arch" + GOOS=$os GOARCH=$arch go build + done + echo2 } set -e cross linux amd64 386 arm arm64 ppc64 ppc64le s390x mips mipsle mips64 mips64le -cross darwin amd64 386 arm arm64 -cross freebsd amd64 386 arm -cross netbsd amd64 386 arm +cross darwin amd64 arm64 +cross freebsd amd64 386 arm arm64 +cross netbsd amd64 386 arm arm64 cross openbsd amd64 386 arm arm64 cross dragonfly amd64 cross solaris amd64 - -# Not expected to work but should still compile. -cross windows amd64 386 arm +cross windows amd64 386 arm # TODO: Fix compilation error on openbsd/arm. # TODO: Merge the solaris PR. # Some os/arch require a different compiler. Run in docker. if ! hash docker; then - # If docker is not present, stop here. - return + # If docker is not present, stop here. + return fi echo2 "Build for linux." echo2 " - linux/riscv" -docker build -t test -f Dockerfile.riscv . +docker build -t creack-pty-test -f Dockerfile.riscv . + +# Golang dropped support for darwin 32bits since go1.15. Make sure the lib still compile with go1.14 on those archs. +echo2 "Build for darwin (32bits)." +echo2 " - darwin/386" +docker build -t creack-pty-test -f Dockerfile.golang --build-arg=GOVERSION=1.14 --build-arg=GOOS=darwin --build-arg=GOARCH=386 . +echo2 " - darwin/arm" +docker build -t creack-pty-test -f Dockerfile.golang --build-arg=GOVERSION=1.14 --build-arg=GOOS=darwin --build-arg=GOARCH=arm . + +# Run a single test for an old go version. Would be best with go1.0, but not available on Dockerhub. +# Using 1.6 as it is the base version for the RISCV compiler. +# Would also be better to run all the tests, not just one, need to refactor this file to allow for specifc archs per version. +echo2 "Build for linux - go1.6." +echo2 " - linux/amd64" +docker build -t creack-pty-test -f Dockerfile.golang --build-arg=GOVERSION=1.6 --build-arg=GOOS=linux --build-arg=GOARCH=amd64 . diff --git a/vendor/github.com/creack/pty/util.go b/vendor/github.com/creack/pty/util.go deleted file mode 100644 index 8fdde0bab..000000000 --- a/vendor/github.com/creack/pty/util.go +++ /dev/null @@ -1,64 +0,0 @@ -// +build !windows,!solaris - -package pty - -import ( - "os" - "syscall" - "unsafe" -) - -// 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 InheritSize(pty, tty *os.File) error { - size, err := GetsizeFull(pty) - if err != nil { - return err - } - err = Setsize(tty, size) - if err != nil { - return err - } - return nil -} - -// Setsize resizes t to s. -func Setsize(t *os.File, ws *Winsize) error { - return windowRectCall(ws, t.Fd(), syscall.TIOCSWINSZ) -} - -// GetsizeFull returns the full terminal size description. -func GetsizeFull(t *os.File) (size *Winsize, err error) { - var ws Winsize - err = windowRectCall(&ws, t.Fd(), syscall.TIOCGWINSZ) - return &ws, err -} - -// Getsize returns the number of rows (lines) and cols (positions -// in each line) in terminal t. -func Getsize(t *os.File) (rows, cols int, err error) { - ws, err := GetsizeFull(t) - return int(ws.Rows), int(ws.Cols), err -} - -// Winsize describes the terminal size. -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 -} - -func windowRectCall(ws *Winsize, fd, a2 uintptr) error { - _, _, errno := syscall.Syscall( - syscall.SYS_IOCTL, - fd, - a2, - uintptr(unsafe.Pointer(ws)), - ) - if errno != 0 { - return syscall.Errno(errno) - } - return nil -} diff --git a/vendor/github.com/creack/pty/util_solaris.go b/vendor/github.com/creack/pty/util_solaris.go deleted file mode 100644 index e88969248..000000000 --- a/vendor/github.com/creack/pty/util_solaris.go +++ /dev/null @@ -1,51 +0,0 @@ -// - -package pty - -import ( - "os" - "golang.org/x/sys/unix" -) - -const ( - TIOCGWINSZ = 21608 // 'T' << 8 | 104 - TIOCSWINSZ = 21607 // 'T' << 8 | 103 -) - -// Winsize describes the terminal size. -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 -} - -// GetsizeFull returns the full terminal size description. -func GetsizeFull(t *os.File) (size *Winsize, err error) { - var wsz *unix.Winsize - wsz, err = unix.IoctlGetWinsize(int(t.Fd()), TIOCGWINSZ) - - if err != nil { - return nil, err - } else { - return &Winsize{wsz.Row, wsz.Col, wsz.Xpixel, wsz.Ypixel}, nil - } -} - -// Get Windows Size -func Getsize(t *os.File) (rows, cols int, err error) { - var wsz *unix.Winsize - wsz, err = unix.IoctlGetWinsize(int(t.Fd()), TIOCGWINSZ) - - if err != nil { - return 80, 25, err - } else { - return int(wsz.Row), int(wsz.Col), nil - } -} - -// Setsize resizes t to s. -func Setsize(t *os.File, ws *Winsize) error { - wsz := unix.Winsize{ws.Rows, ws.Cols, ws.X, ws.Y} - return unix.IoctlSetWinsize(int(t.Fd()), TIOCSWINSZ, &wsz) -} diff --git a/vendor/github.com/creack/pty/winsize.go b/vendor/github.com/creack/pty/winsize.go new file mode 100644 index 000000000..7d3d1fc3a --- /dev/null +++ b/vendor/github.com/creack/pty/winsize.go @@ -0,0 +1,31 @@ +package pty + +// Winsize describes the terminal size. +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 +} + +// 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 InheritSize(pty Pty, tty Tty) error { + size, err := GetsizeFull(pty) + if err != nil { + return err + } + + if err := Setsize(tty, size); err != nil { + return err + } + return nil +} + +// Getsize returns the number of rows (lines) and cols (positions +// in each line) in terminal t. +func Getsize(t FdHolder) (rows, cols int, err error) { + ws, err := GetsizeFull(t) + return int(ws.Rows), int(ws.Cols), err +} diff --git a/vendor/github.com/creack/pty/winsize_unix.go b/vendor/github.com/creack/pty/winsize_unix.go new file mode 100644 index 000000000..d3e7d15c3 --- /dev/null +++ b/vendor/github.com/creack/pty/winsize_unix.go @@ -0,0 +1,26 @@ +//go:build !windows +// +build !windows + +package pty + +import ( + "syscall" + "unsafe" +) + +// Setsize resizes t to s. +func Setsize(t FdHolder, ws *Winsize) error { + //nolint:gosec // Expected unsafe pointer for Syscall call. + return ioctl(t.Fd(), syscall.TIOCSWINSZ, uintptr(unsafe.Pointer(ws))) +} + +// GetsizeFull returns the full terminal size description. +func GetsizeFull(t FdHolder) (size *Winsize, err error) { + var ws Winsize + + //nolint:gosec // Expected unsafe pointer for Syscall call. + if err := ioctl(t.Fd(), syscall.TIOCGWINSZ, uintptr(unsafe.Pointer(&ws))); err != nil { + return nil, err + } + return &ws, nil +} diff --git a/vendor/github.com/creack/pty/winsize_windows.go b/vendor/github.com/creack/pty/winsize_windows.go new file mode 100644 index 000000000..5b960046b --- /dev/null +++ b/vendor/github.com/creack/pty/winsize_windows.go @@ -0,0 +1,89 @@ +//go:build windows +// +build windows + +package pty + +import ( + "syscall" + "unsafe" +) + +// types from golang.org/x/sys/windows +// copy of https://pkg.go.dev/golang.org/x/sys/windows#Coord +type windowsCoord struct { + X int16 + Y int16 +} + +// copy of https://pkg.go.dev/golang.org/x/sys/windows#SmallRect +type windowsSmallRect struct { + Left int16 + Top int16 + Right int16 + Bottom int16 +} + +// copy of https://pkg.go.dev/golang.org/x/sys/windows#ConsoleScreenBufferInfo +type windowsConsoleScreenBufferInfo struct { + Size windowsCoord + CursorPosition windowsCoord + Attributes uint16 + Window windowsSmallRect + MaximumWindowSize windowsCoord +} + +func (c windowsCoord) Pack() uintptr { + return uintptr((int32(c.Y) << 16) | int32(c.X)) +} + +// Setsize resizes t to ws. +func Setsize(t FdHolder, ws *Winsize) error { + var r0 uintptr + var err error + + err = resizePseudoConsole.Find() + if err != nil { + return err + } + + r0, _, err = resizePseudoConsole.Call( + t.Fd(), + (windowsCoord{X: int16(ws.Cols), Y: int16(ws.Rows)}).Pack(), + ) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + + // S_OK: 0 + return syscall.Errno(r0) + } + + return nil +} + +// GetsizeFull returns the full terminal size description. +func GetsizeFull(t FdHolder) (size *Winsize, err error) { + err = getConsoleScreenBufferInfo.Find() + if err != nil { + return nil, err + } + + var info windowsConsoleScreenBufferInfo + var r0 uintptr + + r0, _, err = getConsoleScreenBufferInfo.Call(t.Fd(), uintptr(unsafe.Pointer(&info))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + + // S_OK: 0 + return nil, syscall.Errno(r0) + } + + return &Winsize{ + Rows: uint16(info.Window.Bottom - info.Window.Top + 1), + Cols: uint16(info.Window.Right - info.Window.Left + 1), + }, nil +} diff --git a/vendor/github.com/creack/pty/ztypes_386.go b/vendor/github.com/creack/pty/ztypes_386.go index ff0b8fd83..d126f4aa5 100644 --- a/vendor/github.com/creack/pty/ztypes_386.go +++ b/vendor/github.com/creack/pty/ztypes_386.go @@ -1,3 +1,6 @@ +//go:build 386 +// +build 386 + // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types.go diff --git a/vendor/github.com/creack/pty/ztypes_amd64.go b/vendor/github.com/creack/pty/ztypes_amd64.go index ff0b8fd83..6c4a7677f 100644 --- a/vendor/github.com/creack/pty/ztypes_amd64.go +++ b/vendor/github.com/creack/pty/ztypes_amd64.go @@ -1,3 +1,6 @@ +//go:build amd64 +// +build amd64 + // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types.go diff --git a/vendor/github.com/creack/pty/ztypes_arm.go b/vendor/github.com/creack/pty/ztypes_arm.go index ff0b8fd83..de6fe160e 100644 --- a/vendor/github.com/creack/pty/ztypes_arm.go +++ b/vendor/github.com/creack/pty/ztypes_arm.go @@ -1,3 +1,6 @@ +//go:build arm +// +build arm + // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types.go diff --git a/vendor/github.com/creack/pty/ztypes_arm64.go b/vendor/github.com/creack/pty/ztypes_arm64.go index 6c29a4b91..c4f315cac 100644 --- a/vendor/github.com/creack/pty/ztypes_arm64.go +++ b/vendor/github.com/creack/pty/ztypes_arm64.go @@ -1,8 +1,9 @@ +//go:build arm64 +// +build arm64 + // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types.go -// +build arm64 - package pty type ( diff --git a/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go b/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go index 6b0ba037f..183c42147 100644 --- a/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go +++ b/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go @@ -1,3 +1,6 @@ +//go:build amd64 && dragonfly +// +build amd64,dragonfly + // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_dragonfly.go diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_386.go b/vendor/github.com/creack/pty/ztypes_freebsd_386.go index d9975374e..d80dbf717 100644 --- a/vendor/github.com/creack/pty/ztypes_freebsd_386.go +++ b/vendor/github.com/creack/pty/ztypes_freebsd_386.go @@ -1,3 +1,6 @@ +//go:build 386 && freebsd +// +build 386,freebsd + // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go b/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go index 5fa102fcd..bfab4e458 100644 --- a/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go +++ b/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go @@ -1,3 +1,6 @@ +//go:build amd64 && freebsd +// +build amd64,freebsd + // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_arm.go b/vendor/github.com/creack/pty/ztypes_freebsd_arm.go index d9975374e..3a8aeae37 100644 --- a/vendor/github.com/creack/pty/ztypes_freebsd_arm.go +++ b/vendor/github.com/creack/pty/ztypes_freebsd_arm.go @@ -1,3 +1,6 @@ +//go:build arm && freebsd +// +build arm,freebsd + // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_arm64.go b/vendor/github.com/creack/pty/ztypes_freebsd_arm64.go index 4418139b2..a83924918 100644 --- a/vendor/github.com/creack/pty/ztypes_freebsd_arm64.go +++ b/vendor/github.com/creack/pty/ztypes_freebsd_arm64.go @@ -1,3 +1,6 @@ +//go:build arm64 && freebsd +// +build arm64,freebsd + // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs types_freebsd.go diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_ppc64.go b/vendor/github.com/creack/pty/ztypes_freebsd_ppc64.go new file mode 100644 index 000000000..5fa102fcd --- /dev/null +++ b/vendor/github.com/creack/pty/ztypes_freebsd_ppc64.go @@ -0,0 +1,14 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_freebsd.go + +package pty + +const ( + _C_SPECNAMELEN = 0x3f +) + +type fiodgnameArg struct { + Len int32 + Pad_cgo_0 [4]byte + Buf *byte +} diff --git a/vendor/github.com/creack/pty/ztypes_loong64.go b/vendor/github.com/creack/pty/ztypes_loong64.go new file mode 100644 index 000000000..3beb5c176 --- /dev/null +++ b/vendor/github.com/creack/pty/ztypes_loong64.go @@ -0,0 +1,12 @@ +//go:build loong64 +// +build loong64 + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/creack/pty/ztypes_mipsx.go b/vendor/github.com/creack/pty/ztypes_mipsx.go index f0ce74086..281277977 100644 --- a/vendor/github.com/creack/pty/ztypes_mipsx.go +++ b/vendor/github.com/creack/pty/ztypes_mipsx.go @@ -1,9 +1,10 @@ +//go:build (mips || mipsle || mips64 || mips64le) && linux +// +build mips mipsle mips64 mips64le +// +build linux + // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types.go -// +build linux -// +build mips mipsle mips64 mips64le - package pty type ( diff --git a/vendor/github.com/creack/pty/ztypes_netbsd_32bit_int.go b/vendor/github.com/creack/pty/ztypes_netbsd_32bit_int.go new file mode 100644 index 000000000..2ab7c4559 --- /dev/null +++ b/vendor/github.com/creack/pty/ztypes_netbsd_32bit_int.go @@ -0,0 +1,17 @@ +//go:build (386 || amd64 || arm || arm64) && netbsd +// +build 386 amd64 arm arm64 +// +build netbsd + +package pty + +type ptmget struct { + Cfd int32 + Sfd int32 + Cn [1024]int8 + Sn [1024]int8 +} + +var ( + ioctl_TIOCPTSNAME = 0x48087448 + ioctl_TIOCGRANTPT = 0x20007447 +) diff --git a/vendor/github.com/creack/pty/ztypes_openbsd_32bit_int.go b/vendor/github.com/creack/pty/ztypes_openbsd_32bit_int.go index d7cab4a2a..1eb094816 100644 --- a/vendor/github.com/creack/pty/ztypes_openbsd_32bit_int.go +++ b/vendor/github.com/creack/pty/ztypes_openbsd_32bit_int.go @@ -1,13 +1,14 @@ +//go:build (386 || amd64 || arm || arm64 || mips64) && openbsd +// +build 386 amd64 arm arm64 mips64 // +build openbsd -// +build 386 amd64 arm arm64 package pty type ptmget struct { - Cfd int32 - Sfd int32 - Cn [16]int8 - Sn [16]int8 + Cfd int32 + Sfd int32 + Cn [16]int8 + Sn [16]int8 } var ioctl_PTMGET = 0x40287401 diff --git a/vendor/github.com/creack/pty/ztypes_ppc64.go b/vendor/github.com/creack/pty/ztypes_ppc64.go index 4e1af8431..bbb3da832 100644 --- a/vendor/github.com/creack/pty/ztypes_ppc64.go +++ b/vendor/github.com/creack/pty/ztypes_ppc64.go @@ -1,3 +1,4 @@ +//go:build ppc64 // +build ppc64 // Created by cgo -godefs - DO NOT EDIT diff --git a/vendor/github.com/creack/pty/ztypes_ppc64le.go b/vendor/github.com/creack/pty/ztypes_ppc64le.go index e6780f4e2..8a4fac3e9 100644 --- a/vendor/github.com/creack/pty/ztypes_ppc64le.go +++ b/vendor/github.com/creack/pty/ztypes_ppc64le.go @@ -1,3 +1,4 @@ +//go:build ppc64le // +build ppc64le // Created by cgo -godefs - DO NOT EDIT diff --git a/vendor/github.com/creack/pty/ztypes_riscvx.go b/vendor/github.com/creack/pty/ztypes_riscvx.go index 99eec8ecb..dc5da9050 100644 --- a/vendor/github.com/creack/pty/ztypes_riscvx.go +++ b/vendor/github.com/creack/pty/ztypes_riscvx.go @@ -1,8 +1,9 @@ +//go:build riscv || riscv64 +// +build riscv riscv64 + // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs types.go -// +build riscv riscv64 - package pty type ( diff --git a/vendor/github.com/creack/pty/ztypes_s390x.go b/vendor/github.com/creack/pty/ztypes_s390x.go index a7452b61c..3433be7ca 100644 --- a/vendor/github.com/creack/pty/ztypes_s390x.go +++ b/vendor/github.com/creack/pty/ztypes_s390x.go @@ -1,3 +1,4 @@ +//go:build s390x // +build s390x // Created by cgo -godefs - DO NOT EDIT diff --git a/vendor/modules.txt b/vendor/modules.txt index fd06a3ec6..5837e793d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -13,7 +13,7 @@ github.com/cli/safeexec # github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 ## explicit github.com/cloudfoundry/jibber_jabber -# github.com/creack/pty v1.1.11 +# github.com/creack/pty v1.1.11 => github.com/photostorm/pty v1.1.19-0.20230324012736-6794a5ba0ba0 ## explicit; go 1.13 github.com/creack/pty # github.com/davecgh/go-spew v1.1.1 @@ -320,3 +320,4 @@ gopkg.in/warnings.v0 # gopkg.in/yaml.v3 v3.0.1 ## explicit gopkg.in/yaml.v3 +# github.com/creack/pty => github.com/photostorm/pty v1.1.19-0.20230324012736-6794a5ba0ba0