Download
27 lines 753 BGoModified 2026-10-31 raw
123456789101112131415161718192021222324252627
//go:build linux || darwin

package pty

import (
	"os"
	"syscall"
	"unsafe"
)

// KeyMode has a terminal pass each key as it is typed, without echoing
// it, for a question one key answers, and returns how to put it back.
// Unlike raw mode, it keeps the keys that send signals: Ctrl-C still
// interrupts.
func KeyMode(f *os.File) (restore func() error, err error) {
	var was syscall.Termios
	if err := ioctl(f, getTermios, unsafe.Pointer(&was)); err != nil {
		return nil, err
	}
	t := was
	t.Lflag &^= syscall.ICANON | syscall.ECHO
	t.Cc[syscall.VMIN], t.Cc[syscall.VTIME] = 1, 0
	if err := ioctl(f, setTermios, unsafe.Pointer(&t)); err != nil {
		return nil, err
	}
	return func() error { return ioctl(f, setTermios, unsafe.Pointer(&was)) }, nil
}