Drop one dependency
This commit is contained in:
parent
73e4deb1c2
commit
13758e9600
1
go.mod
1
go.mod
@ -5,7 +5,6 @@ go 1.19
|
|||||||
require (
|
require (
|
||||||
github.com/mattn/go-isatty v0.0.14
|
github.com/mattn/go-isatty v0.0.14
|
||||||
github.com/mattn/go-runewidth v0.0.13
|
github.com/mattn/go-runewidth v0.0.13
|
||||||
github.com/pkg/term v1.1.0
|
|
||||||
github.com/seancfoley/ipaddress-go v1.2.1
|
github.com/seancfoley/ipaddress-go v1.2.1
|
||||||
github.com/spf13/cobra v1.5.0
|
github.com/spf13/cobra v1.5.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
|
|||||||
3
go.sum
3
go.sum
@ -5,8 +5,6 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9
|
|||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk=
|
|
||||||
github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw=
|
|
||||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
@ -20,7 +18,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
|||||||
@ -92,26 +92,23 @@ func create_serializer(password string, encoded_pubkey string, response_timeout
|
|||||||
return simple_serializer, timeout, nil
|
return simple_serializer, timeout, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type TTYIO interface {
|
type IOAbstraction interface {
|
||||||
WriteAllWithTimeout(b []byte, d time.Duration) (n int, err error)
|
WriteAllWithTimeout(b []byte, d time.Duration) (n int, err error)
|
||||||
WriteFromReader(r utils.Reader, read_timeout time.Duration, write_timeout time.Duration) (n int, err error)
|
WriteFromReader(r utils.Reader, read_timeout time.Duration, write_timeout time.Duration) (n int, err error)
|
||||||
ReadWithTimeout(b []byte, d time.Duration) (n int, err error)
|
ReadWithTimeout(b []byte, d time.Duration) (n int, err error)
|
||||||
|
|
||||||
Restore() error
|
|
||||||
Close() error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func do_tty_io(tty TTYIO, input utils.Reader, no_response bool, response_timeout time.Duration) (serialized_response []byte, err error) {
|
func do_io(device IOAbstraction, input utils.Reader, no_response bool, response_timeout time.Duration) (serialized_response []byte, err error) {
|
||||||
|
|
||||||
_, err = tty.WriteAllWithTimeout([]byte("\x1bP@kitty-cmd"), 2*time.Second)
|
_, err = device.WriteAllWithTimeout([]byte("\x1bP@kitty-cmd"), 2*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = tty.WriteFromReader(input, 2*time.Second, 2*time.Second)
|
_, err = device.WriteFromReader(input, 2*time.Second, 2*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = tty.WriteAllWithTimeout([]byte("\x1b\\"), 2*time.Second)
|
_, err = device.WriteAllWithTimeout([]byte("\x1b\\"), 2*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -135,7 +132,7 @@ func do_tty_io(tty TTYIO, input utils.Reader, no_response bool, response_timeout
|
|||||||
for !response_received {
|
for !response_received {
|
||||||
buf = buf[:cap(buf)]
|
buf = buf[:cap(buf)]
|
||||||
var n int
|
var n int
|
||||||
n, err = tty.ReadWithTimeout(buf, response_timeout)
|
n, err = device.ReadWithTimeout(buf, response_timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == os.ErrDeadlineExceeded {
|
if err == os.ErrDeadlineExceeded {
|
||||||
err = fmt.Errorf("Timed out while waiting for a response from kitty")
|
err = fmt.Errorf("Timed out while waiting for a response from kitty")
|
||||||
@ -184,22 +181,24 @@ func get_response(rc *utils.RemoteControlCmd, timeout float64) (ans *Response, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var tty TTYIO
|
var device IOAbstraction
|
||||||
if global_options.to_network == "" {
|
if global_options.to_network == "" {
|
||||||
tty, err = utils.OpenControllingTerm(true)
|
var term *utils.Term
|
||||||
|
term, err = utils.OpenControllingTerm(utils.SetRaw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
term.Restore()
|
||||||
|
term.Close()
|
||||||
|
}()
|
||||||
|
device = term
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("TODO: Implement socket IO")
|
err = fmt.Errorf("TODO: Implement socket IO")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
tty.Restore()
|
|
||||||
tty.Close()
|
|
||||||
}()
|
|
||||||
r := utils.BytesReader{Data: d}
|
r := utils.BytesReader{Data: d}
|
||||||
serialized_response, err := do_tty_io(tty, &r, rc.NoResponse, time.Duration(timeout*float64(time.Second)))
|
serialized_response, err := do_io(device, &r, rc.NoResponse, time.Duration(timeout*float64(time.Second)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == os.ErrDeadlineExceeded {
|
if err == os.ErrDeadlineExceeded {
|
||||||
rc.Payload = nil
|
rc.Payload = nil
|
||||||
@ -209,7 +208,7 @@ func get_response(rc *utils.RemoteControlCmd, timeout float64) (ans *Response, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = do_tty_io(tty, &r, rc.NoResponse, 0)
|
_, err = do_io(device, &r, rc.NoResponse, 0)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,10 +9,15 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/term/termios"
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TCSANOW = 0
|
||||||
|
TCSADRAIN = 1
|
||||||
|
TCSAFLUSH = 2
|
||||||
|
)
|
||||||
|
|
||||||
type Term struct {
|
type Term struct {
|
||||||
name string
|
name string
|
||||||
fd int
|
fd int
|
||||||
@ -39,7 +44,46 @@ func eintr_retry_intret(f func() (int, error)) (int, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func OpenTerm(name string, in_raw_mode bool) (self *Term, err error) {
|
type TermiosOperation func(t *unix.Termios)
|
||||||
|
|
||||||
|
func get_vmin_and_vtime(d time.Duration) (uint8, uint8) {
|
||||||
|
if d > 0 {
|
||||||
|
// VTIME is expressed in terms of deciseconds
|
||||||
|
vtimeDeci := d.Milliseconds() / 100
|
||||||
|
// ensure valid range
|
||||||
|
vtime := uint8(clamp(vtimeDeci, 1, 0xff))
|
||||||
|
return 0, vtime
|
||||||
|
}
|
||||||
|
// block indefinitely until we receive at least 1 byte
|
||||||
|
return 1, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetReadTimeout(d time.Duration) TermiosOperation {
|
||||||
|
vmin, vtime := get_vmin_and_vtime(d)
|
||||||
|
return func(t *unix.Termios) {
|
||||||
|
t.Cc[unix.VMIN] = vmin
|
||||||
|
t.Cc[unix.VTIME] = vtime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var SetBlockingRead TermiosOperation = SetReadTimeout(0)
|
||||||
|
|
||||||
|
var SetRaw TermiosOperation = func(t *unix.Termios) {
|
||||||
|
// This attempts to replicate the behaviour documented for cfmakeraw in
|
||||||
|
// the termios(3) manpage, as Go doesnt wrap cfmakeraw probably because its not in POSIX
|
||||||
|
t.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
|
||||||
|
t.Oflag &^= unix.OPOST
|
||||||
|
t.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
|
||||||
|
t.Cflag &^= unix.CSIZE | unix.PARENB
|
||||||
|
t.Cflag |= unix.CS8
|
||||||
|
t.Cc[unix.VMIN] = 1
|
||||||
|
t.Cc[unix.VTIME] = 0
|
||||||
|
}
|
||||||
|
var SetNoEcho TermiosOperation = func(t *unix.Termios) {
|
||||||
|
t.Lflag &^= unix.ECHO
|
||||||
|
}
|
||||||
|
|
||||||
|
func OpenTerm(name string, operations ...TermiosOperation) (self *Term, err error) {
|
||||||
fd, err := eintr_retry_intret(func() (int, error) {
|
fd, err := eintr_retry_intret(func() (int, error) {
|
||||||
return unix.Open(name, unix.O_NOCTTY|unix.O_CLOEXEC|unix.O_NDELAY|unix.O_RDWR, 0666)
|
return unix.Open(name, unix.O_NOCTTY|unix.O_CLOEXEC|unix.O_NDELAY|unix.O_RDWR, 0666)
|
||||||
})
|
})
|
||||||
@ -49,20 +93,18 @@ func OpenTerm(name string, in_raw_mode bool) (self *Term, err error) {
|
|||||||
|
|
||||||
self = &Term{name: name, fd: fd}
|
self = &Term{name: name, fd: fd}
|
||||||
err = eintr_retry_noret(func() error { return unix.SetNonblock(self.fd, false) })
|
err = eintr_retry_noret(func() error { return unix.SetNonblock(self.fd, false) })
|
||||||
if err != nil {
|
if err == nil {
|
||||||
return
|
err = self.ApplyOperations(TCSANOW, operations...)
|
||||||
}
|
}
|
||||||
if in_raw_mode {
|
if err != nil {
|
||||||
err = self.SetRaw()
|
self.Close()
|
||||||
if err != nil {
|
self = nil
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func OpenControllingTerm(in_raw_mode bool) (self *Term, err error) {
|
func OpenControllingTerm(operations ...TermiosOperation) (self *Term, err error) {
|
||||||
return OpenTerm("/dev/tty", in_raw_mode) // go doesnt have a wrapper for ctermid()
|
return OpenTerm("/dev/tty", operations...) // go doesnt have a wrapper for ctermid()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Term) Fd() int { return self.fd }
|
func (self *Term) Fd() int { return self.fd }
|
||||||
@ -74,28 +116,32 @@ func (self *Term) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Term) Tcgetattr(ans *unix.Termios) error {
|
func (self *Term) Tcgetattr(ans *unix.Termios) error {
|
||||||
return eintr_retry_noret(func() error { return termios.Tcgetattr(uintptr(self.fd), ans) })
|
return eintr_retry_noret(func() error { return Tcgetattr(self.fd, ans) })
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Term) Tcsetattr(when uintptr, ans *unix.Termios) error {
|
func (self *Term) Tcsetattr(when uintptr, ans *unix.Termios) error {
|
||||||
return eintr_retry_noret(func() error { return termios.Tcsetattr(uintptr(self.fd), when, ans) })
|
return eintr_retry_noret(func() error { return Tcsetattr(self.fd, when, ans) })
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Term) SetRawWhen(when uintptr) (err error) {
|
func (self *Term) set_termios_attrs(when uintptr, modify func(*unix.Termios)) (err error) {
|
||||||
var state unix.Termios
|
var state unix.Termios
|
||||||
if err = self.Tcgetattr(&state); err != nil {
|
if err = self.Tcgetattr(&state); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
new_state := state
|
new_state := state
|
||||||
termios.Cfmakeraw(&new_state)
|
modify(&new_state)
|
||||||
if err = self.Tcsetattr(when, &new_state); err == nil {
|
if err = self.Tcsetattr(when, &new_state); err == nil {
|
||||||
self.states = append(self.states, state)
|
self.states = append(self.states, state)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Term) SetRaw() error {
|
func (self *Term) ApplyOperations(when uintptr, operations ...TermiosOperation) (err error) {
|
||||||
return self.SetRawWhen(termios.TCSANOW)
|
return self.set_termios_attrs(when, func(t *unix.Termios) {
|
||||||
|
for _, op := range operations {
|
||||||
|
op(t)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Term) PopStateWhen(when uintptr) (err error) {
|
func (self *Term) PopStateWhen(when uintptr) (err error) {
|
||||||
@ -110,7 +156,7 @@ func (self *Term) PopStateWhen(when uintptr) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Term) PopState() error {
|
func (self *Term) PopState() error {
|
||||||
return self.PopStateWhen(termios.TCIOFLUSH)
|
return self.PopStateWhen(TCSAFLUSH)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Term) RestoreWhen(when uintptr) (err error) {
|
func (self *Term) RestoreWhen(when uintptr) (err error) {
|
||||||
@ -122,7 +168,7 @@ func (self *Term) RestoreWhen(when uintptr) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Term) Restore() error {
|
func (self *Term) Restore() error {
|
||||||
return self.RestoreWhen(termios.TCIOFLUSH)
|
return self.RestoreWhen(TCSAFLUSH)
|
||||||
}
|
}
|
||||||
|
|
||||||
func clamp(v, lo, hi int64) int64 {
|
func clamp(v, lo, hi int64) int64 {
|
||||||
@ -135,31 +181,6 @@ func clamp(v, lo, hi int64) int64 {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_vmin_and_vtime(d time.Duration) (uint8, uint8) {
|
|
||||||
if d > 0 {
|
|
||||||
// VTIME is expressed in terms of deciseconds
|
|
||||||
vtimeDeci := d.Milliseconds() / 100
|
|
||||||
// ensure valid range
|
|
||||||
vtime := uint8(clamp(vtimeDeci, 1, 0xff))
|
|
||||||
return 0, vtime
|
|
||||||
}
|
|
||||||
// block indefinitely until we receive at least 1 byte
|
|
||||||
return 1, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Term) SetReadTimeout(d time.Duration) (err error) {
|
|
||||||
var a unix.Termios
|
|
||||||
if err := self.Tcgetattr(&a); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b := a
|
|
||||||
b.Cc[unix.VMIN], b.Cc[unix.VTIME] = get_vmin_and_vtime(d)
|
|
||||||
if err = self.Tcsetattr(termios.TCSANOW, &b); err == nil {
|
|
||||||
self.states = append(self.states, a)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Term) ReadWithTimeout(b []byte, d time.Duration) (n int, err error) {
|
func (self *Term) ReadWithTimeout(b []byte, d time.Duration) (n int, err error) {
|
||||||
var read, write, in_err unix.FdSet
|
var read, write, in_err unix.FdSet
|
||||||
pselect := func() (int, error) {
|
pselect := func() (int, error) {
|
||||||
|
|||||||
26
tools/utils/tty_bsd.go
Normal file
26
tools/utils/tty_bsd.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//go:build darwin || freebsd || openbsd || netbsd || dragonfly
|
||||||
|
// +build darwin freebsd openbsd netbsd dragonfly
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Tcgetattr(fd uintptr, argp *unix.Termios) error {
|
||||||
|
return unix.IoctlSetTermios(int(fd), unix.TIOCGETA, argp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Tcsetattr(fd, opt uintptr, argp *unix.Termios) error {
|
||||||
|
switch opt {
|
||||||
|
case TCSANOW:
|
||||||
|
opt = unix.TIOCSETA
|
||||||
|
case TCSADRAIN:
|
||||||
|
opt = unix.TIOCSETAW
|
||||||
|
case TCSAFLUSH:
|
||||||
|
opt = unix.TIOCSETAF
|
||||||
|
default:
|
||||||
|
return unix.EINVAL
|
||||||
|
}
|
||||||
|
return unix.IoctlSetTermios(int(fd), uint(opt), argp)
|
||||||
|
}
|
||||||
36
tools/utils/tty_linux.go
Normal file
36
tools/utils/tty_linux.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
const (
|
||||||
|
TCSETS = 0x5402
|
||||||
|
TCSETSW = 0x5403
|
||||||
|
TCSETSF = 0x5404
|
||||||
|
TCFLSH = 0x540B
|
||||||
|
TCSBRK = 0x5409
|
||||||
|
TCSBRKP = 0x5425
|
||||||
|
|
||||||
|
IXON = 0x00000400
|
||||||
|
IXANY = 0x00000800
|
||||||
|
IXOFF = 0x00001000
|
||||||
|
CRTSCTS = 0x80000000
|
||||||
|
)
|
||||||
|
|
||||||
|
func Tcgetattr(fd int, argp *unix.Termios) error {
|
||||||
|
return unix.IoctlSetTermios(fd, unix.TCGETS, argp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Tcsetattr(fd int, action uintptr, argp *unix.Termios) error {
|
||||||
|
var request uintptr
|
||||||
|
switch action {
|
||||||
|
case TCSANOW:
|
||||||
|
request = TCSETS
|
||||||
|
case TCSADRAIN:
|
||||||
|
request = TCSETSW
|
||||||
|
case TCSAFLUSH:
|
||||||
|
request = TCSETSF
|
||||||
|
default:
|
||||||
|
return unix.EINVAL
|
||||||
|
}
|
||||||
|
return unix.IoctlSetTermios(int(fd), uint(request), argp)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user