| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- package termutil
- import (
- "errors"
- "os"
- "os/signal"
- "sync"
- )
- var echoLocked bool
- var echoLockMutex sync.Mutex
- var errLocked = errors.New("terminal locked")
- // 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)
- signal.Notify(sig, unlockSignals...)
- defer signal.Stop(sig)
- select {
- case <-quit:
- RawModeOff()
- case <-sig:
- RawModeOff()
- }
- }
|