diff options
Diffstat (limited to 'vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go')
-rw-r--r-- | vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go | 118 |
1 files changed, 63 insertions, 55 deletions
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go index 12e6fe6e2..af4251760 100644 --- a/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go +++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go @@ -1,5 +1,5 @@ // +build linux darwin freebsd netbsd openbsd solaris dragonfly -// +build !appengine +// +build !appengine !js package pb @@ -8,101 +8,109 @@ import ( "fmt" "os" "os/signal" - "runtime" "sync" "syscall" - "unsafe" -) -const ( - TIOCGWINSZ = 0x5413 - TIOCGWINSZ_OSX = 1074295912 + "golang.org/x/sys/unix" ) -var tty *os.File - var ErrPoolWasStarted = errors.New("Bar pool was started") -var echoLocked bool -var echoLockMutex sync.Mutex +var ( + echoLockMutex sync.Mutex + origTermStatePtr *unix.Termios + tty *os.File + istty bool +) func init() { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + var err error tty, err = os.Open("/dev/tty") + istty = true if err != nil { tty = os.Stdin + istty = false } } // terminalWidth returns width of the terminal. func terminalWidth() (int, error) { - w := new(window) - tio := syscall.TIOCGWINSZ - if runtime.GOOS == "darwin" { - tio = TIOCGWINSZ_OSX + if !istty { + return 0, errors.New("Not Supported") } - res, _, err := syscall.Syscall(sysIoctl, - tty.Fd(), - uintptr(tio), - uintptr(unsafe.Pointer(w)), - ) - if int(res) == -1 { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + + fd := int(tty.Fd()) + + ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) + if err != nil { return 0, err } - return int(w.Col), nil -} -var oldState syscall.Termios + return int(ws.Col), nil +} -func lockEcho() (quit chan int, err error) { +func lockEcho() (shutdownCh chan struct{}, err error) { echoLockMutex.Lock() defer echoLockMutex.Unlock() - if echoLocked { - err = ErrPoolWasStarted - return - } - echoLocked = true + if istty { + if origTermStatePtr != nil { + return shutdownCh, ErrPoolWasStarted + } - fd := tty.Fd() - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't get terminal settings: %v", e) - return - } + fd := int(tty.Fd()) + + origTermStatePtr, err = unix.IoctlGetTermios(fd, ioctlReadTermios) + if err != nil { + return nil, fmt.Errorf("Can't get terminal settings: %v", err) + } + + oldTermios := *origTermStatePtr + newTermios := oldTermios + newTermios.Lflag &^= syscall.ECHO + newTermios.Lflag |= syscall.ICANON | syscall.ISIG + newTermios.Iflag |= syscall.ICRNL + if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newTermios); err != nil { + return nil, fmt.Errorf("Can't set terminal settings: %v", err) + } - newState := oldState - newState.Lflag &^= syscall.ECHO - newState.Lflag |= syscall.ICANON | syscall.ISIG - newState.Iflag |= syscall.ICRNL - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings: %v", e) - return } - quit = make(chan int, 1) - go catchTerminate(quit) + shutdownCh = make(chan struct{}) + go catchTerminate(shutdownCh) return } -func unlockEcho() (err error) { +func unlockEcho() error { echoLockMutex.Lock() defer echoLockMutex.Unlock() - if !echoLocked { - return - } - echoLocked = false - fd := tty.Fd() - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings") + if istty { + if origTermStatePtr == nil { + return nil + } + + fd := int(tty.Fd()) + + if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, origTermStatePtr); err != nil { + return fmt.Errorf("Can't set terminal settings: %v", err) + } + } - return + origTermStatePtr = nil + + return nil } // listen exit signals and restore terminal state -func catchTerminate(quit chan int) { +func catchTerminate(shutdownCh chan struct{}) { sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL) defer signal.Stop(sig) select { - case <-quit: + case <-shutdownCh: unlockEcho() case <-sig: unlockEcho() |