VictoriaMetrics/vendor/github.com/dmitryk-dk/pb/v3/termutil/term.go
Dmytro Kozlov 1a8a24bcb3
vmctl: fix build for solaris os (#2555)
* vmctl: fix build for solaris os

* vmctl: updated dependency (using Syscall instead of Syscall6)

* vmctl: updated dependency

* vmctl: updated dependency
2022-05-11 14:30:45 +03:00

69 lines
1.3 KiB
Go

package termutil
import (
"errors"
"os"
"os/signal"
"sync"
)
var echoLocked bool
var echoLockMutex sync.Mutex
var errLocked = errors.New("terminal locked")
var autoTerminate = true
// AutoTerminate enables or disables automatic terminate signal catching.
// It's needed to restore the terminal state after the pool was used.
// By default, it's enabled.
func AutoTerminate(enable bool) {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
autoTerminate = enable
}
// RawModeOn switches terminal to raw mode
func RawModeOn() (quit chan struct{}, err error) {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
if echoLocked {
err = errLocked
return
}
if err = lockEcho(); err != nil {
return
}
echoLocked = true
quit = make(chan struct{}, 1)
go catchTerminate(quit)
return
}
// RawModeOff restore previous terminal state
func RawModeOff() (err error) {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
if !echoLocked {
return
}
if err = unlockEcho(); err != nil {
return
}
echoLocked = false
return
}
// listen exit signals and restore terminal state
func catchTerminate(quit chan struct{}) {
sig := make(chan os.Signal, 1)
if autoTerminate {
signal.Notify(sig, unlockSignals...)
defer signal.Stop(sig)
}
select {
case <-quit:
RawModeOff()
case <-sig:
RawModeOff()
}
}