mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
helper/wrappedreadline: helper for dealing with wrapped standard streams
This commit is contained in:
parent
6272b969d4
commit
73a1564dac
84
helper/wrappedreadline/wrappedreadline.go
Normal file
84
helper/wrappedreadline/wrappedreadline.go
Normal file
@ -0,0 +1,84 @@
|
||||
// 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.
|
||||
package wrappedreadline
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/chzyer/readline"
|
||||
)
|
||||
|
||||
// These are the file descriptor numbers for the original stdin, stdout, stderr
|
||||
// streams from the parent process.
|
||||
const (
|
||||
StdinFd = 3
|
||||
StdoutFd = 4
|
||||
StderrFd = 5
|
||||
)
|
||||
|
||||
// These are the *os.File values for the standard streams.
|
||||
var (
|
||||
Stdin = os.NewFile(uintptr(StdinFd), "stdin")
|
||||
Stdout = os.NewFile(uintptr(StdoutFd), "stdout")
|
||||
Stderr = os.NewFile(uintptr(StderrFd), "stderr")
|
||||
)
|
||||
|
||||
// Override overrides the values in readline.Config that need to be
|
||||
// set with wrapped values.
|
||||
func Override(cfg *readline.Config) *readline.Config {
|
||||
cfg.Stdin = Stdin
|
||||
cfg.Stdout = Stdout
|
||||
cfg.Stderr = Stderr
|
||||
|
||||
cfg.FuncGetWidth = TerminalWidth
|
||||
cfg.FuncIsTerminal = IsTerminal
|
||||
|
||||
var rm RawMode
|
||||
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(StdinFd) && (readline.IsTerminal(StdoutFd) || readline.IsTerminal(StderrFd))
|
||||
}
|
||||
|
||||
// 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 {
|
||||
state *readline.State
|
||||
}
|
||||
|
||||
func (r *RawMode) Enter() (err error) {
|
||||
r.state, err = readline.MakeRaw(StdinFd)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *RawMode) Exit() error {
|
||||
if r.state == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return readline.Restore(StdinFd, r.state)
|
||||
}
|
41
helper/wrappedreadline/wrappedreadline_unix.go
Normal file
41
helper/wrappedreadline/wrappedreadline_unix.go
Normal file
@ -0,0 +1,41 @@
|
||||
// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
|
||||
|
||||
package wrappedreadline
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// getWidth impl for Unix
|
||||
func getWidth() int {
|
||||
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)
|
||||
}
|
8
helper/wrappedreadline/wrappedreadline_windows.go
Normal file
8
helper/wrappedreadline/wrappedreadline_windows.go
Normal file
@ -0,0 +1,8 @@
|
||||
// +build windows
|
||||
|
||||
package wrappedreadline
|
||||
|
||||
// getWidth impl for other
|
||||
func getWidth() int {
|
||||
return 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user