forked from peco/peco
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tty_windows.go
61 lines (52 loc) · 1.27 KB
/
tty_windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package peco
import (
"os"
"syscall"
"unsafe"
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
procGetConsoleMode = kernel32.MustFindProc("GetConsoleMode")
)
func getStdHandle(h int) (fd syscall.Handle) {
r, _ := syscall.GetStdHandle(h)
syscall.CloseOnExec(r)
return r
}
func setStdHandle(stdhandle int32, handle syscall.Handle) error {
r1, _, err := procSetStdHandle.Call(uintptr(stdhandle), uintptr(handle))
if r1 == 0 && err != nil {
return err
}
return nil
}
// IsTty checks if the given fd is a tty
func IsTty(fd uintptr) bool {
var st uint32
r1, _, err := procGetConsoleMode.Call(fd, uintptr(unsafe.Pointer(&st)))
return r1 != 0 && err != nil
}
var stdin = os.Stdin
// TtyReady checks if the tty is ready to go
func TtyReady() error {
var err error
_stdin, err := os.Open("CONIN$")
if err != nil {
return err
}
stdin = os.Stdin
os.Stdin = _stdin
syscall.Stdin = syscall.Handle(os.Stdin.Fd())
err = setStdHandle(syscall.STD_INPUT_HANDLE, syscall.Stdin)
if err != nil {
return err
}
return nil
}
// TtyTerm restores any state, if necessary
func TtyTerm() {
os.Stdin = stdin
syscall.Stdin = syscall.Handle(os.Stdin.Fd())
setStdHandle(syscall.STD_INPUT_HANDLE, syscall.Stdin)
}