213 lines
5.4 KiB
Go
213 lines
5.4 KiB
Go
// +build !windows
|
|
|
|
package code
|
|
|
|
import (
|
|
"os"
|
|
"syscall"
|
|
)
|
|
|
|
// POSIX terminal mode flags as listed in RFC 4254 Section 8.
|
|
const (
|
|
tty_OP_END = 0
|
|
VINTR = 1
|
|
VQUIT = 2
|
|
VERASE = 3
|
|
VKILL = 4
|
|
VEOF = 5
|
|
VEOL = 6
|
|
VEOL2 = 7
|
|
VSTART = 8
|
|
VSTOP = 9
|
|
VSUSP = 10
|
|
VDSUSP = 11
|
|
VREPRINT = 12
|
|
VWERASE = 13
|
|
VLNEXT = 14
|
|
VFLUSH = 15
|
|
VSWTCH = 16
|
|
VSTATUS = 17
|
|
VDISCARD = 18
|
|
IGNPAR = 30
|
|
PARMRK = 31
|
|
INPCK = 32
|
|
ISTRIP = 33
|
|
INLCR = 34
|
|
IGNCR = 35
|
|
ICRNL = 36
|
|
IUCLC = 37
|
|
IXON = 38
|
|
IXANY = 39
|
|
IXOFF = 40
|
|
IMAXBEL = 41
|
|
IUTF8 = 42
|
|
ISIG = 50
|
|
ICANON = 51
|
|
XCASE = 52
|
|
ECHO = 53
|
|
ECHOE = 54
|
|
ECHOK = 55
|
|
ECHONL = 56
|
|
NOFLSH = 57
|
|
TOSTOP = 58
|
|
IEXTEN = 59
|
|
ECHOCTL = 60
|
|
ECHOKE = 61
|
|
PENDIN = 62
|
|
OPOST = 70
|
|
OLCUC = 71
|
|
ONLCR = 72
|
|
OCRNL = 73
|
|
ONOCR = 74
|
|
ONLRET = 75
|
|
CS7 = 90
|
|
CS8 = 91
|
|
PARENB = 92
|
|
PARODD = 93
|
|
TTY_OP_ISPEED = 128
|
|
TTY_OP_OSPEED = 129
|
|
)
|
|
|
|
// struct termios {
|
|
// tcflag_t c_iflag; /* input modes */
|
|
// tcflag_t c_oflag; /* output modes */
|
|
// tcflag_t c_cflag; /* control modes */
|
|
// tcflag_t c_lflag; /* local modes */
|
|
// cc_t c_cc[NCCS]; /* special characters */
|
|
// speed_t c_ispeed;
|
|
// speed_t c_ospeed;
|
|
// };
|
|
|
|
type Setter interface {
|
|
Set(pty *os.File, termios *syscall.Termios, value uint32) error
|
|
}
|
|
|
|
var TermAttrSetters = map[uint8]Setter{
|
|
VINTR: &ccSetter{Character: syscall.VINTR},
|
|
VQUIT: &ccSetter{Character: syscall.VQUIT},
|
|
VERASE: &ccSetter{Character: syscall.VERASE},
|
|
VKILL: &ccSetter{Character: syscall.VKILL},
|
|
VEOF: &ccSetter{Character: syscall.VEOF},
|
|
VEOL: &ccSetter{Character: syscall.VEOL},
|
|
VEOL2: &ccSetter{Character: syscall.VEOL2},
|
|
VSTART: &ccSetter{Character: syscall.VSTART},
|
|
VSTOP: &ccSetter{Character: syscall.VSTOP},
|
|
VSUSP: &ccSetter{Character: syscall.VSUSP},
|
|
VDSUSP: &nopSetter{},
|
|
VREPRINT: &ccSetter{Character: syscall.VREPRINT},
|
|
VWERASE: &ccSetter{Character: syscall.VWERASE},
|
|
VLNEXT: &ccSetter{Character: syscall.VLNEXT},
|
|
VFLUSH: &nopSetter{},
|
|
VSWTCH: &nopSetter{},
|
|
VSTATUS: &nopSetter{},
|
|
VDISCARD: &ccSetter{Character: syscall.VDISCARD},
|
|
|
|
// Input modes
|
|
IGNPAR: &iflagSetter{Flag: syscall.IGNPAR},
|
|
PARMRK: &iflagSetter{Flag: syscall.PARMRK},
|
|
INPCK: &iflagSetter{Flag: syscall.INPCK},
|
|
ISTRIP: &iflagSetter{Flag: syscall.ISTRIP},
|
|
INLCR: &iflagSetter{Flag: syscall.INLCR},
|
|
IGNCR: &iflagSetter{Flag: syscall.IGNCR},
|
|
ICRNL: &iflagSetter{Flag: syscall.ICRNL},
|
|
IUCLC: &nopSetter{},
|
|
IXON: &iflagSetter{Flag: syscall.IXON},
|
|
IXANY: &iflagSetter{Flag: syscall.IXANY},
|
|
IXOFF: &iflagSetter{Flag: syscall.IXOFF},
|
|
IMAXBEL: &iflagSetter{Flag: syscall.IMAXBEL},
|
|
IUTF8: &iflagSetter{Flag: syscall.IUTF8}, //IUTF8
|
|
|
|
// Local modes
|
|
ISIG: &lflagSetter{Flag: syscall.ISIG},
|
|
ICANON: &lflagSetter{Flag: syscall.ICANON},
|
|
XCASE: &nopSetter{},
|
|
ECHO: &lflagSetter{Flag: syscall.ECHO},
|
|
ECHOE: &lflagSetter{Flag: syscall.ECHOE},
|
|
ECHOK: &lflagSetter{Flag: syscall.ECHOK},
|
|
ECHONL: &lflagSetter{Flag: syscall.ECHONL},
|
|
NOFLSH: &lflagSetter{Flag: syscall.NOFLSH},
|
|
TOSTOP: &lflagSetter{Flag: syscall.TOSTOP},
|
|
IEXTEN: &lflagSetter{Flag: syscall.IEXTEN},
|
|
ECHOCTL: &lflagSetter{Flag: syscall.ECHOCTL},
|
|
ECHOKE: &lflagSetter{Flag: syscall.ECHOKE},
|
|
PENDIN: &lflagSetter{Flag: syscall.PENDIN},
|
|
|
|
// Output modes
|
|
OPOST: &oflagSetter{Flag: syscall.OPOST},
|
|
OLCUC: &nopSetter{},
|
|
ONLCR: &oflagSetter{Flag: syscall.ONLCR},
|
|
OCRNL: &oflagSetter{Flag: syscall.OCRNL},
|
|
ONOCR: &oflagSetter{Flag: syscall.ONOCR},
|
|
ONLRET: &oflagSetter{Flag: syscall.ONLRET},
|
|
|
|
// Control modes
|
|
CS7: &cflagSetter{Flag: syscall.CS7},
|
|
CS8: &cflagSetter{Flag: syscall.CS8},
|
|
PARENB: &cflagSetter{Flag: syscall.PARENB},
|
|
PARODD: &cflagSetter{Flag: syscall.PARODD},
|
|
|
|
// Baud rates (ignore)
|
|
TTY_OP_ISPEED: &nopSetter{},
|
|
TTY_OP_OSPEED: &nopSetter{},
|
|
}
|
|
|
|
type nopSetter struct{}
|
|
|
|
type ccSetter struct {
|
|
Character uint8
|
|
}
|
|
|
|
func (cc *ccSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error {
|
|
termios.Cc[cc.Character] = byte(value)
|
|
return SetAttr(pty, termios)
|
|
}
|
|
|
|
func (i *iflagSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error {
|
|
if value == 0 {
|
|
termios.Iflag &^= i.Flag
|
|
} else {
|
|
termios.Iflag |= i.Flag
|
|
}
|
|
return SetAttr(pty, termios)
|
|
}
|
|
|
|
func (l *lflagSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error {
|
|
if value == 0 {
|
|
termios.Lflag &^= l.Flag
|
|
} else {
|
|
termios.Lflag |= l.Flag
|
|
}
|
|
return SetAttr(pty, termios)
|
|
}
|
|
|
|
func (o *oflagSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error {
|
|
if value == 0 {
|
|
termios.Oflag &^= o.Flag
|
|
} else {
|
|
termios.Oflag |= o.Flag
|
|
}
|
|
|
|
return SetAttr(pty, termios)
|
|
}
|
|
|
|
func (c *cflagSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error {
|
|
switch c.Flag {
|
|
// CSIZE is a field
|
|
case syscall.CS7, syscall.CS8:
|
|
termios.Cflag &^= syscall.CSIZE
|
|
termios.Cflag |= c.Flag
|
|
default:
|
|
if value == 0 {
|
|
termios.Cflag &^= c.Flag
|
|
} else {
|
|
termios.Cflag |= c.Flag
|
|
}
|
|
}
|
|
|
|
return SetAttr(pty, termios)
|
|
}
|
|
|
|
func (n *nopSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error {
|
|
return nil
|
|
}
|