Commit c417a082 by Ian Lance Taylor

exp/terminal: Use tcgetattr/tcsetattr rather than ioctl.

From-SVN: r180780
parent e1bb1acc
...@@ -17,7 +17,6 @@ package terminal ...@@ -17,7 +17,6 @@ package terminal
import ( import (
"os" "os"
"syscall" "syscall"
"unsafe"
) )
// State contains the state of a terminal. // State contains the state of a terminal.
...@@ -28,7 +27,7 @@ type State struct { ...@@ -28,7 +27,7 @@ type State struct {
// IsTerminal returns true if the given file descriptor is a terminal. // IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool { func IsTerminal(fd int) bool {
var termios syscall.Termios var termios syscall.Termios
_, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&termios)), 0, 0, 0) e := syscall.Tcgetattr(fd, &termios)
return e == 0 return e == 0
} }
...@@ -37,14 +36,14 @@ func IsTerminal(fd int) bool { ...@@ -37,14 +36,14 @@ func IsTerminal(fd int) bool {
// restored. // restored.
func MakeRaw(fd int) (*State, os.Error) { func MakeRaw(fd int) (*State, os.Error) {
var oldState State var oldState State
if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); e != 0 { if e := syscall.Tcgetattr(fd, &oldState.termios); e != 0 {
return nil, os.Errno(e) return nil, os.Errno(e)
} }
newState := oldState.termios newState := oldState.termios
newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF
newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { if e := syscall.Tcsetattr(fd, syscall.TCSANOW, &newState); e != 0 {
return nil, os.Errno(e) return nil, os.Errno(e)
} }
...@@ -54,7 +53,7 @@ func MakeRaw(fd int) (*State, os.Error) { ...@@ -54,7 +53,7 @@ func MakeRaw(fd int) (*State, os.Error) {
// Restore restores the terminal connected to the given file descriptor to a // Restore restores the terminal connected to the given file descriptor to a
// previous state. // previous state.
func Restore(fd int, state *State) os.Error { func Restore(fd int, state *State) os.Error {
_, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0) e := syscall.Tcsetattr(fd, syscall.TCSANOW, &state.termios)
return os.Errno(e) return os.Errno(e)
} }
...@@ -63,18 +62,18 @@ func Restore(fd int, state *State) os.Error { ...@@ -63,18 +62,18 @@ func Restore(fd int, state *State) os.Error {
// returned does not include the \n. // returned does not include the \n.
func ReadPassword(fd int) ([]byte, os.Error) { func ReadPassword(fd int) ([]byte, os.Error) {
var oldState syscall.Termios var oldState syscall.Termios
if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { if e := syscall.Tcgetattr(fd, &oldState); e != 0 {
return nil, os.Errno(e) return nil, os.Errno(e)
} }
newState := oldState newState := oldState
newState.Lflag &^= syscall.ECHO newState.Lflag &^= syscall.ECHO
if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { if e := syscall.Tcsetattr(fd, syscall.TCSANOW, &newState); e != 0 {
return nil, os.Errno(e) return nil, os.Errno(e)
} }
defer func() { defer func() {
syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) syscall.Tcsetattr(fd, syscall.TCSANOW, &oldState)
}() }()
var buf [16]byte var buf [16]byte
......
...@@ -377,3 +377,9 @@ func NsecToTimeval(nsec int64) (tv Timeval) { ...@@ -377,3 +377,9 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
tv.Usec = Timeval_usec_t(nsec % 1e9 / 1e3) tv.Usec = Timeval_usec_t(nsec % 1e9 / 1e3)
return return
} }
//sysnb Tcgetattr(fd int, p *Termios) (errno int)
//tcgetattr(fd int, p *Termios) int
//sys Tcsetattr(fd int, actions int, p *Termios) (errno int)
//tcsetattr(fd int, actions int, p *Termios) int
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment