summaryrefslogtreecommitdiff
path: root/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go')
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go110
1 files changed, 110 insertions, 0 deletions
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go
new file mode 100644
index 000000000..12e6fe6e2
--- /dev/null
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go
@@ -0,0 +1,110 @@
+// +build linux darwin freebsd netbsd openbsd solaris dragonfly
+// +build !appengine
+
+package pb
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "os/signal"
+ "runtime"
+ "sync"
+ "syscall"
+ "unsafe"
+)
+
+const (
+ TIOCGWINSZ = 0x5413
+ TIOCGWINSZ_OSX = 1074295912
+)
+
+var tty *os.File
+
+var ErrPoolWasStarted = errors.New("Bar pool was started")
+
+var echoLocked bool
+var echoLockMutex sync.Mutex
+
+func init() {
+ var err error
+ tty, err = os.Open("/dev/tty")
+ if err != nil {
+ tty = os.Stdin
+ }
+}
+
+// terminalWidth returns width of the terminal.
+func terminalWidth() (int, error) {
+ w := new(window)
+ tio := syscall.TIOCGWINSZ
+ if runtime.GOOS == "darwin" {
+ tio = TIOCGWINSZ_OSX
+ }
+ res, _, err := syscall.Syscall(sysIoctl,
+ tty.Fd(),
+ uintptr(tio),
+ uintptr(unsafe.Pointer(w)),
+ )
+ if int(res) == -1 {
+ return 0, err
+ }
+ return int(w.Col), nil
+}
+
+var oldState syscall.Termios
+
+func lockEcho() (quit chan int, err error) {
+ echoLockMutex.Lock()
+ defer echoLockMutex.Unlock()
+ if echoLocked {
+ err = ErrPoolWasStarted
+ return
+ }
+ echoLocked = true
+
+ 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
+ }
+
+ 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)
+ return
+}
+
+func unlockEcho() (err 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")
+ }
+ return
+}
+
+// listen exit signals and restore terminal state
+func catchTerminate(quit chan int) {
+ sig := make(chan os.Signal, 1)
+ signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL)
+ defer signal.Stop(sig)
+ select {
+ case <-quit:
+ unlockEcho()
+ case <-sig:
+ unlockEcho()
+ }
+}