-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f48c8f1
commit aaaa5ac
Showing
14 changed files
with
482 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//go:build netbsd || openbsd | ||
// +build netbsd openbsd | ||
|
||
package termios | ||
|
||
func speed(b uint32) int32 { return int32(b) } | ||
func bit(b uint32) uint32 { return b } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//go:build darwin | ||
// +build darwin | ||
|
||
package termios | ||
|
||
func speed(b uint32) uint64 { return uint64(b) } | ||
func bit(b uint32) uint64 { return uint64(b) } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//go:build !darwin && !netbsd && !openbsd | ||
// +build !darwin,!netbsd,!openbsd | ||
|
||
package termios | ||
|
||
func speed(b uint32) uint32 { return b } | ||
func bit(b uint32) uint32 { return b } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/charmbracelet/x/termios | ||
|
||
go 1.18 | ||
|
||
require golang.org/x/sys v0.20.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= | ||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
//go:build darwin && netbsd && freebsd && netbsd | ||
// +build darwin,netbsd,freebsd,netbsd | ||
|
||
package term | ||
|
||
import "syscall" | ||
|
||
func init() { | ||
allCcOpts[STATUS] = syscall.VSTATUS | ||
allCcOpts[DSUSP] = syscall.VDSUSP | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
//go:build darwin | ||
// +build darwin | ||
|
||
package termios | ||
|
||
import "syscall" | ||
|
||
func init() { | ||
allLineOpts[IUTF8] = syscall.IUTF8 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
//go:build linux | ||
// +build linux | ||
|
||
package termios | ||
|
||
import "syscall" | ||
|
||
func init() { | ||
allCcOpts[SWTCH] = syscall.VSWTC | ||
allInputOpts[IUCLC] = syscall.IUCLC | ||
allLineOpts[IUTF8] = syscall.IUTF8 | ||
allLineOpts[XCASE] = syscall.XCASE | ||
allOutputOpts[OLCUC] = syscall.OLCUC | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,249 @@ | ||
//go:build darwin || netbsd || freebsd || openbsd || linux || dragonfly || solaris | ||
// +build darwin netbsd freebsd openbsd linux dragonfly solaris | ||
|
||
package termios | ||
|
||
import ( | ||
"syscall" | ||
|
||
"golang.org/x/sys/unix" | ||
) | ||
|
||
// SetWinsize sets window size for an fd from a Winsize. | ||
func SetWinsize(fd int, w *unix.Winsize) error { | ||
return unix.IoctlSetWinsize(fd, ioctlSetWinSize, w) | ||
} | ||
|
||
// GetWinsize gets window size for an fd. | ||
func GetWinsize(fd int) (*unix.Winsize, error) { | ||
return unix.IoctlGetWinsize(fd, ioctlSetWinSize) | ||
} | ||
|
||
// GetTermios gets the termios of the given fd. | ||
func GetTermios(fd int) (*unix.Termios, error) { | ||
return unix.IoctlGetTermios(fd, ioctlGets) | ||
} | ||
|
||
// SetTermios sets the given termios over the given fd's current termios. | ||
func SetTermios( | ||
fd int, | ||
ispeed uint32, | ||
ospeed uint32, | ||
cc map[CC]uint8, | ||
iflag map[I]bool, | ||
oflag map[O]bool, | ||
cflag map[C]bool, | ||
lflag map[L]bool, | ||
) error { | ||
term, err := unix.IoctlGetTermios(fd, ioctlGets) | ||
if err != nil { | ||
return err | ||
} | ||
setSpeed(term, ispeed, ospeed) | ||
|
||
for key, value := range cc { | ||
call, ok := allCcOpts[key] | ||
if !ok { | ||
continue | ||
} | ||
term.Cc[call] = value | ||
} | ||
|
||
for key, value := range iflag { | ||
mask, ok := allInputOpts[key] | ||
if ok { | ||
if value { | ||
term.Iflag |= bit(mask) | ||
} else { | ||
term.Iflag &= ^bit(mask) | ||
} | ||
} | ||
} | ||
for key, value := range oflag { | ||
mask, ok := allOutputOpts[key] | ||
if ok { | ||
if value { | ||
term.Oflag |= bit(mask) | ||
} else { | ||
term.Oflag &= ^bit(mask) | ||
} | ||
} | ||
} | ||
for key, value := range cflag { | ||
mask, ok := allControlOpts[key] | ||
if ok { | ||
if value { | ||
term.Cflag |= bit(mask) | ||
} else { | ||
term.Cflag &= ^bit(mask) | ||
} | ||
} | ||
} | ||
for key, value := range lflag { | ||
mask, ok := allLineOpts[key] | ||
if ok { | ||
if value { | ||
term.Lflag |= bit(mask) | ||
} else { | ||
term.Lflag &= ^bit(mask) | ||
} | ||
} | ||
} | ||
return unix.IoctlSetTermios(fd, ioctlSets, term) | ||
} | ||
|
||
// CC is the termios cc field. | ||
// | ||
// It stores an array of special characters related to terminal I/O. | ||
type CC uint8 | ||
|
||
// CC possible values. | ||
const ( | ||
INTR CC = iota | ||
QUIT | ||
ERASE | ||
KILL | ||
EOF | ||
EOL | ||
EOL2 | ||
START | ||
STOP | ||
SUSP | ||
WERASE | ||
RPRNT | ||
LNEXT | ||
DISCARD | ||
STATUS | ||
SWTCH | ||
DSUSP | ||
FLUSH | ||
) | ||
|
||
// https://www.man7.org/linux/man-pages/man3/termios.3.html | ||
var allCcOpts = map[CC]int{ | ||
INTR: syscall.VINTR, | ||
QUIT: syscall.VQUIT, | ||
ERASE: syscall.VERASE, | ||
KILL: syscall.VQUIT, | ||
EOF: syscall.VEOF, | ||
EOL: syscall.VEOL, | ||
EOL2: syscall.VEOL2, | ||
START: syscall.VSTART, | ||
STOP: syscall.VSTOP, | ||
SUSP: syscall.VSUSP, | ||
WERASE: syscall.VWERASE, | ||
RPRNT: syscall.VREPRINT, | ||
LNEXT: syscall.VLNEXT, | ||
DISCARD: syscall.VDISCARD, | ||
|
||
// XXX: these syscalls don't exist for any OS | ||
// FLUSH: syscall.VFLUSH, | ||
} | ||
|
||
// Input Controls | ||
type I uint8 | ||
|
||
// Input possible values. | ||
const ( | ||
IGNPAR I = iota | ||
PARMRK | ||
INPCK | ||
ISTRIP | ||
INLCR | ||
IGNCR | ||
ICRNL | ||
IXON | ||
IXANY | ||
IXOFF | ||
IMAXBEL | ||
IUCLC | ||
) | ||
|
||
var allInputOpts = map[I]uint32{ | ||
IGNPAR: syscall.IGNPAR, | ||
PARMRK: syscall.PARMRK, | ||
INPCK: syscall.INPCK, | ||
ISTRIP: syscall.ISTRIP, | ||
INLCR: syscall.INLCR, | ||
IGNCR: syscall.IGNCR, | ||
ICRNL: syscall.ICRNL, | ||
IXON: syscall.IXON, | ||
IXANY: syscall.IXANY, | ||
IXOFF: syscall.IXOFF, | ||
IMAXBEL: syscall.IMAXBEL, | ||
} | ||
|
||
// Output Controls | ||
type O uint8 | ||
|
||
// Output possible values. | ||
const ( | ||
OPOST O = iota | ||
ONLCR | ||
OCRNL | ||
ONOCR | ||
ONLRET | ||
OLCUC | ||
) | ||
|
||
var allOutputOpts = map[O]uint32{ | ||
OPOST: syscall.OPOST, | ||
ONLCR: syscall.ONLCR, | ||
OCRNL: syscall.OCRNL, | ||
ONOCR: syscall.ONOCR, | ||
ONLRET: syscall.ONLRET, | ||
} | ||
|
||
// Control | ||
type C uint8 | ||
|
||
// Control possible values. | ||
const ( | ||
CS7 C = iota | ||
CS8 | ||
PARENB | ||
PARODD | ||
) | ||
|
||
var allControlOpts = map[C]uint32{ | ||
CS7: syscall.CS7, | ||
CS8: syscall.CS8, | ||
PARENB: syscall.PARENB, | ||
PARODD: syscall.PARODD, | ||
} | ||
|
||
// Line Controls. | ||
type L uint8 | ||
|
||
// Line possible values. | ||
const ( | ||
ISIG L = iota | ||
ICANON | ||
ECHO | ||
ECHOE | ||
ECHOK | ||
ECHONL | ||
NOFLSH | ||
TOSTOP | ||
IEXTEN | ||
ECHOCTL | ||
ECHOKE | ||
PENDIN | ||
IUTF8 | ||
XCASE | ||
) | ||
|
||
var allLineOpts = map[L]uint32{ | ||
ISIG: syscall.ISIG, | ||
ICANON: syscall.ICANON, | ||
ECHO: syscall.ECHO, | ||
ECHOE: syscall.ECHOE, | ||
ECHOK: syscall.ECHOK, | ||
ECHONL: syscall.ECHONL, | ||
NOFLSH: syscall.NOFLSH, | ||
TOSTOP: syscall.TOSTOP, | ||
IEXTEN: syscall.IEXTEN, | ||
ECHOCTL: syscall.ECHOCTL, | ||
ECHOKE: syscall.ECHOKE, | ||
PENDIN: syscall.PENDIN, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
//go:build darwin || netbsd || freebsd || openbsd || dragonfly | ||
// +build darwin netbsd freebsd openbsd dragonfly | ||
|
||
package termios | ||
|
||
import "golang.org/x/sys/unix" | ||
|
||
const ( | ||
ioctlGets = unix.TIOCGETA | ||
ioctlSets = unix.TIOCSETA | ||
ioctlGetWinSize = unix.TIOCGWINSZ | ||
ioctlSetWinSize = unix.TIOCSWINSZ | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
//go:build linux | ||
// +build linux | ||
|
||
package termios | ||
|
||
import "golang.org/x/sys/unix" | ||
|
||
const ( | ||
ioctlGets = unix.TCGETS | ||
ioctlSets = unix.TCSETS | ||
ioctlGetWinSize = unix.TIOCGWINSZ | ||
ioctlSetWinSize = unix.TIOCSWINSZ | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
//go:build darwin || netbsd || freebsd || openbsd || linux || dragonfly | ||
// +build darwin netbsd freebsd openbsd linux dragonfly | ||
|
||
package termios | ||
|
||
import "golang.org/x/sys/unix" | ||
|
||
func setSpeed(term *unix.Termios, ispeed, ospeed uint32) { | ||
term.Ispeed = speed(ispeed) | ||
term.Ospeed = speed(ospeed) | ||
} | ||
|
||
func getSpeed(term *unix.Termios) (uint32, uint32) { | ||
return uint32(term.Ispeed), uint32(term.Ospeed) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
//go:build solaris | ||
// +build solaris | ||
|
||
package termios | ||
|
||
import "golang.org/x/sys/unix" | ||
|
||
// see https://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/isatty.c | ||
// see https://github.com/omniti-labs/illumos-omnios/blob/master/usr/src/uts/common/sys/termios.h | ||
const ( | ||
ioctlSets = unix.TCSETA | ||
ioctlGets = unix.TCGETA | ||
ioctlSetWinSize = (int('T') << 8) | 103 | ||
ioctlGetWinSize = (int('T') << 8) | 104 | ||
) | ||
|
||
func setSpeed(*unix.Termios, uint32, uint32) { | ||
// TODO: support setting speed on Solaris? | ||
// see cfgetospeed(3C) and cfsetospeed(3C) | ||
// see cfgetispeed(3C) and cfsetispeed(3C) | ||
// https://github.com/omniti-labs/illumos-omnios/blob/master/usr/src/uts/common/sys/termios.h#L103 | ||
} | ||
|
||
func getSpeed(*unix.Termios) (uint32, uint32) { | ||
return 0, 0 | ||
} |
Oops, something went wrong.