remove wrapped streams and readline

This commit is contained in:
James Bardin 2021-10-27 10:28:19 -04:00
parent 622c4df14c
commit 42742c173d
8 changed files with 8 additions and 256 deletions

View File

@ -3,11 +3,11 @@ package command
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"os"
"strings" "strings"
"github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/backend" "github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/helper/wrappedstreams"
"github.com/hashicorp/terraform/internal/repl" "github.com/hashicorp/terraform/internal/repl"
"github.com/hashicorp/terraform/internal/terraform" "github.com/hashicorp/terraform/internal/terraform"
"github.com/hashicorp/terraform/internal/tfdiags" "github.com/hashicorp/terraform/internal/tfdiags"
@ -113,8 +113,8 @@ func (c *ConsoleCommand) Run(args []string) int {
// Set up the UI so we can output directly to stdout // Set up the UI so we can output directly to stdout
ui := &cli.BasicUi{ ui := &cli.BasicUi{
Writer: wrappedstreams.Stdout(), Writer: os.Stdout,
ErrorWriter: wrappedstreams.Stderr(), ErrorWriter: os.Stderr,
} }
evalOpts := &terraform.EvalOpts{} evalOpts := &terraform.EvalOpts{}
@ -164,7 +164,7 @@ func (c *ConsoleCommand) Run(args []string) int {
func (c *ConsoleCommand) modePiped(session *repl.Session, ui cli.Ui) int { func (c *ConsoleCommand) modePiped(session *repl.Session, ui cli.Ui) int {
var lastResult string var lastResult string
scanner := bufio.NewScanner(wrappedstreams.Stdin()) scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() { for scanner.Scan() {
result, exit, diags := session.Handle(strings.TrimSpace(scanner.Text())) result, exit, diags := session.Handle(strings.TrimSpace(scanner.Text()))
if diags.HasErrors() { if diags.HasErrors() {

View File

@ -9,6 +9,7 @@ package command
import ( import (
"fmt" "fmt"
"io" "io"
"os"
"github.com/hashicorp/terraform/internal/repl" "github.com/hashicorp/terraform/internal/repl"
@ -23,6 +24,9 @@ func (c *ConsoleCommand) modeInteractive(session *repl.Session, ui cli.Ui) int {
InterruptPrompt: "^C", InterruptPrompt: "^C",
EOFPrompt: "exit", EOFPrompt: "exit",
HistorySearchFold: true, HistorySearchFold: true,
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}) })
if err != nil { if err != nil {
c.Ui.Error(fmt.Sprintf( c.Ui.Error(fmt.Sprintf(

View File

@ -1,77 +0,0 @@
// wrappedreadline is a package that has helpers for interacting with
// readline from a panicwrap executable.
//
// panicwrap overrides the standard file descriptors so that the child process
// no longer looks like a TTY. The helpers here access the extra file descriptors
// passed by panicwrap to fix that.
//
// panicwrap should be checked for with panicwrap.Wrapped before using this
// librar, since this library won't adapt if the binary is not wrapped.
package wrappedreadline
import (
"runtime"
"github.com/chzyer/readline"
"github.com/hashicorp/terraform/internal/helper/wrappedstreams"
)
// Override overrides the values in readline.Config that need to be
// set with wrapped values.
func Override(cfg *readline.Config) *readline.Config {
cfg.Stdin = wrappedstreams.Stdin()
cfg.Stdout = wrappedstreams.Stdout()
cfg.Stderr = wrappedstreams.Stderr()
cfg.FuncGetWidth = TerminalWidth
cfg.FuncIsTerminal = IsTerminal
rm := RawMode{StdinFd: int(wrappedstreams.Stdin().Fd())}
cfg.FuncMakeRaw = rm.Enter
cfg.FuncExitRaw = rm.Exit
return cfg
}
// IsTerminal determines if this process is attached to a TTY.
func IsTerminal() bool {
// Windows is always a terminal
if runtime.GOOS == "windows" {
return true
}
// Same implementation as readline but with our custom fds
return readline.IsTerminal(int(wrappedstreams.Stdin().Fd())) &&
(readline.IsTerminal(int(wrappedstreams.Stdout().Fd())) ||
readline.IsTerminal(int(wrappedstreams.Stderr().Fd())))
}
// TerminalWidth gets the terminal width in characters.
func TerminalWidth() int {
if runtime.GOOS == "windows" {
return readline.GetScreenWidth()
}
return getWidth()
}
// RawMode is a helper for entering and exiting raw mode.
type RawMode struct {
StdinFd int
state *readline.State
}
func (r *RawMode) Enter() (err error) {
r.state, err = readline.MakeRaw(r.StdinFd)
return err
}
func (r *RawMode) Exit() error {
if r.state == nil {
return nil
}
return readline.Restore(r.StdinFd, r.state)
}

View File

@ -1,47 +0,0 @@
//go:build darwin || dragonfly || freebsd || (linux && !appengine) || netbsd || openbsd
// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
package wrappedreadline
import (
"syscall"
"unsafe"
"github.com/hashicorp/terraform/internal/helper/wrappedstreams"
)
// getWidth impl for Unix
func getWidth() int {
stdoutFd := int(wrappedstreams.Stdout().Fd())
stderrFd := int(wrappedstreams.Stderr().Fd())
w := getWidthFd(stdoutFd)
if w < 0 {
w = getWidthFd(stderrFd)
}
return w
}
type winsize struct {
Row uint16
Col uint16
Xpixel uint16
Ypixel uint16
}
// get width of the terminal
func getWidthFd(stdoutFd int) int {
ws := &winsize{}
retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
uintptr(stdoutFd),
uintptr(syscall.TIOCGWINSZ),
uintptr(unsafe.Pointer(ws)))
if int(retCode) == -1 {
_ = errno
return -1
}
return int(ws.Col)
}

View File

@ -1,9 +0,0 @@
//go:build windows
// +build windows
package wrappedreadline
// getWidth impl for other
func getWidth() int {
return 0
}

View File

@ -1,44 +0,0 @@
// Package wrappedstreams provides access to the standard OS streams
// (stdin, stdout, stderr) even if wrapped under panicwrap.
package wrappedstreams
import (
"os"
"github.com/mitchellh/panicwrap"
)
// Stdin returns the true stdin of the process.
func Stdin() *os.File {
stdin, _, _ := fds()
return stdin
}
// Stdout returns the true stdout of the process.
func Stdout() *os.File {
_, stdout, _ := fds()
return stdout
}
// Stderr returns the true stderr of the process.
func Stderr() *os.File {
_, _, stderr := fds()
return stderr
}
func fds() (stdin, stdout, stderr *os.File) {
stdin, stdout, stderr = os.Stdin, os.Stdout, os.Stderr
if panicwrap.Wrapped(nil) {
initPlatform()
stdin, stdout, stderr = wrappedStdin, wrappedStdout, wrappedStderr
}
return
}
// These are the wrapped standard streams. These are set up by the
// platform specific code in initPlatform.
var (
wrappedStdin *os.File
wrappedStdout *os.File
wrappedStderr *os.File
)

View File

@ -1,22 +0,0 @@
//go:build !windows
// +build !windows
package wrappedstreams
import (
"os"
"sync"
)
var initOnce sync.Once
func initPlatform() {
// These must be initialized lazily, once it's been determined that this is
// a wrapped process.
initOnce.Do(func() {
// The standard streams are passed in via extra file descriptors.
wrappedStdin = os.NewFile(uintptr(3), "stdin")
wrappedStdout = os.NewFile(uintptr(4), "stdout")
wrappedStderr = os.NewFile(uintptr(5), "stderr")
})
}

View File

@ -1,53 +0,0 @@
//go:build windows
// +build windows
package wrappedstreams
import (
"log"
"os"
"syscall"
)
func initPlatform() {
wrappedStdin = openConsole("CONIN$", os.Stdin)
wrappedStdout = openConsole("CONOUT$", os.Stdout)
wrappedStderr = wrappedStdout
}
// openConsole opens a console handle, using a backup if it fails.
// This is used to get the exact console handle instead of the redirected
// handles from panicwrap.
func openConsole(name string, backup *os.File) *os.File {
// Convert to UTF16
path, err := syscall.UTF16PtrFromString(name)
if err != nil {
log.Printf("[ERROR] wrappedstreams: %s", err)
return backup
}
// Determine the share mode
var shareMode uint32
switch name {
case "CONIN$":
shareMode = syscall.FILE_SHARE_READ
case "CONOUT$":
shareMode = syscall.FILE_SHARE_WRITE
}
// Get the file
h, err := syscall.CreateFile(
path,
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
shareMode,
nil,
syscall.OPEN_EXISTING,
0, 0)
if err != nil {
log.Printf("[ERROR] wrappedstreams: %s", err)
return backup
}
// Create the Go file
return os.NewFile(uintptr(h), name)
}