Gibheer
fa05045d31
This is the import from the separate monfront repository. The history could not be imported, but this should suffice.
92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
// Copyright 2019 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd zos
|
|
|
|
package term
|
|
|
|
import (
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
type state struct {
|
|
termios unix.Termios
|
|
}
|
|
|
|
func isTerminal(fd int) bool {
|
|
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
|
return err == nil
|
|
}
|
|
|
|
func makeRaw(fd int) (*State, error) {
|
|
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
oldState := State{state{termios: *termios}}
|
|
|
|
// This attempts to replicate the behaviour documented for cfmakeraw in
|
|
// the termios(3) manpage.
|
|
termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
|
|
termios.Oflag &^= unix.OPOST
|
|
termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
|
|
termios.Cflag &^= unix.CSIZE | unix.PARENB
|
|
termios.Cflag |= unix.CS8
|
|
termios.Cc[unix.VMIN] = 1
|
|
termios.Cc[unix.VTIME] = 0
|
|
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &oldState, nil
|
|
}
|
|
|
|
func getState(fd int) (*State, error) {
|
|
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &State{state{termios: *termios}}, nil
|
|
}
|
|
|
|
func restore(fd int, state *State) error {
|
|
return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios)
|
|
}
|
|
|
|
func getSize(fd int) (width, height int, err error) {
|
|
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
|
|
if err != nil {
|
|
return -1, -1, err
|
|
}
|
|
return int(ws.Col), int(ws.Row), nil
|
|
}
|
|
|
|
// passwordReader is an io.Reader that reads from a specific file descriptor.
|
|
type passwordReader int
|
|
|
|
func (r passwordReader) Read(buf []byte) (int, error) {
|
|
return unix.Read(int(r), buf)
|
|
}
|
|
|
|
func readPassword(fd int) ([]byte, error) {
|
|
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
newState := *termios
|
|
newState.Lflag &^= unix.ECHO
|
|
newState.Lflag |= unix.ICANON | unix.ISIG
|
|
newState.Iflag |= unix.ICRNL
|
|
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer unix.IoctlSetTermios(fd, ioctlWriteTermios, termios)
|
|
|
|
return readPasswordLine(passwordReader(fd))
|
|
}
|