...
1
2
3
4 package term
5
6 import (
7 "errors"
8 "io"
9 "os"
10
11 "golang.org/x/sys/unix"
12 )
13
14
15
16
17 var ErrInvalidState = errors.New("Invalid terminal state")
18
19
20 type terminalState struct {
21 termios unix.Termios
22 }
23
24 func stdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
25 return os.Stdin, os.Stdout, os.Stderr
26 }
27
28 func getFdInfo(in interface{}) (uintptr, bool) {
29 var inFd uintptr
30 var isTerminalIn bool
31 if file, ok := in.(*os.File); ok {
32 inFd = file.Fd()
33 isTerminalIn = isTerminal(inFd)
34 }
35 return inFd, isTerminalIn
36 }
37
38 func getWinsize(fd uintptr) (*Winsize, error) {
39 uws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ)
40 ws := &Winsize{Height: uws.Row, Width: uws.Col, x: uws.Xpixel, y: uws.Ypixel}
41 return ws, err
42 }
43
44 func setWinsize(fd uintptr, ws *Winsize) error {
45 return unix.IoctlSetWinsize(int(fd), unix.TIOCSWINSZ, &unix.Winsize{
46 Row: ws.Height,
47 Col: ws.Width,
48 Xpixel: ws.x,
49 Ypixel: ws.y,
50 })
51 }
52
53 func isTerminal(fd uintptr) bool {
54 _, err := tcget(fd)
55 return err == nil
56 }
57
58 func restoreTerminal(fd uintptr, state *State) error {
59 if state == nil {
60 return errors.New("invalid terminal state")
61 }
62 return tcset(fd, &state.termios)
63 }
64
65 func saveState(fd uintptr) (*State, error) {
66 termios, err := tcget(fd)
67 if err != nil {
68 return nil, err
69 }
70 return &State{termios: *termios}, nil
71 }
72
73 func disableEcho(fd uintptr, state *State) error {
74 newState := state.termios
75 newState.Lflag &^= unix.ECHO
76
77 return tcset(fd, &newState)
78 }
79
80 func setRawTerminal(fd uintptr) (*State, error) {
81 return makeRaw(fd)
82 }
83
84 func setRawTerminalOutput(fd uintptr) (*State, error) {
85 return nil, nil
86 }
87
88 func tcget(fd uintptr) (*unix.Termios, error) {
89 p, err := unix.IoctlGetTermios(int(fd), getTermios)
90 if err != nil {
91 return nil, err
92 }
93 return p, nil
94 }
95
96 func tcset(fd uintptr, p *unix.Termios) error {
97 return unix.IoctlSetTermios(int(fd), setTermios, p)
98 }
99
View as plain text