github.com/hs0210/hashicorp-terraform@v0.11.12-beta1/helper/wrappedreadline/wrappedreadline.go (about) 1 // wrappedreadline is a package that has helpers for interacting with 2 // readline from a panicwrap executable. 3 // 4 // panicwrap overrides the standard file descriptors so that the child process 5 // no longer looks like a TTY. The helpers here access the extra file descriptors 6 // passed by panicwrap to fix that. 7 // 8 // panicwrap should be checked for with panicwrap.Wrapped before using this 9 // librar, since this library won't adapt if the binary is not wrapped. 10 package wrappedreadline 11 12 import ( 13 "runtime" 14 15 "github.com/chzyer/readline" 16 17 "github.com/hashicorp/terraform/helper/wrappedstreams" 18 ) 19 20 // Override overrides the values in readline.Config that need to be 21 // set with wrapped values. 22 func Override(cfg *readline.Config) *readline.Config { 23 cfg.Stdin = wrappedstreams.Stdin() 24 cfg.Stdout = wrappedstreams.Stdout() 25 cfg.Stderr = wrappedstreams.Stderr() 26 27 cfg.FuncGetWidth = TerminalWidth 28 cfg.FuncIsTerminal = IsTerminal 29 30 rm := RawMode{StdinFd: int(wrappedstreams.Stdin().Fd())} 31 cfg.FuncMakeRaw = rm.Enter 32 cfg.FuncExitRaw = rm.Exit 33 34 return cfg 35 } 36 37 // IsTerminal determines if this process is attached to a TTY. 38 func IsTerminal() bool { 39 // Windows is always a terminal 40 if runtime.GOOS == "windows" { 41 return true 42 } 43 44 // Same implementation as readline but with our custom fds 45 return readline.IsTerminal(int(wrappedstreams.Stdin().Fd())) && 46 (readline.IsTerminal(int(wrappedstreams.Stdout().Fd())) || 47 readline.IsTerminal(int(wrappedstreams.Stderr().Fd()))) 48 } 49 50 // TerminalWidth gets the terminal width in characters. 51 func TerminalWidth() int { 52 if runtime.GOOS == "windows" { 53 return readline.GetScreenWidth() 54 } 55 56 return getWidth() 57 } 58 59 // RawMode is a helper for entering and exiting raw mode. 60 type RawMode struct { 61 StdinFd int 62 63 state *readline.State 64 } 65 66 func (r *RawMode) Enter() (err error) { 67 r.state, err = readline.MakeRaw(r.StdinFd) 68 return err 69 } 70 71 func (r *RawMode) Exit() error { 72 if r.state == nil { 73 return nil 74 } 75 76 return readline.Restore(r.StdinFd, r.state) 77 }