Files
Packer-Cn/helper/wrappedreadline/wrappedreadline.go
hashicorp-copywrite[bot] 19055df3ec [COMPLIANCE] License changes (#12568)
* Updating the license from MPL to Business Source License

Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at https://hashi.co/license-faq, and details of the license at www.hashicorp.com/bsl.

* Update copyright file headers to BUSL-1.1

---------

Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-10 15:53:29 -07:00

86 lines
2.2 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
// STOLEN SHAMELESSLY FROM THE TERRAFORM REPO BECAUSE VENDORING OUT
// WRAPPEDREADLINE AND WRAPPEDSTREAMS FELT LIKE TOO MUCH WORK.
//
// "a little copying is better than a lot of dependency"
//
// 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/packer/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)
}