From ae4bfd41ff922e06afa9d92b53b9611d2c55cf27 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Sat, 22 Dec 2012 11:02:28 -0500 Subject: [PATCH] ssh/terminal: add GetState and make ReadPassword work in raw mode. GetState is useful for restoring the terminal in a signal handler. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/6990043 --- util.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/util.go b/util.go index daa36d7..93dbbda 100644 --- a/util.go +++ b/util.go @@ -53,6 +53,17 @@ func MakeRaw(fd int) (*State, error) { return &oldState, nil } +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + var oldState State + if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { + return nil, err + } + + return &oldState, nil +} + // Restore restores the terminal connected to the given file descriptor to a // previous state. func Restore(fd int, state *State) error { @@ -81,6 +92,8 @@ func ReadPassword(fd int) ([]byte, error) { newState := oldState newState.Lflag &^= syscall.ECHO + newState.Lflag |= syscall.ICANON | syscall.ISIG + newState.Iflag |= syscall.ICRNL if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { return nil, err }