Skip to content

Instantly share code, notes, and snippets.

@kr

kr/noecho.go Secret

Created January 25, 2013 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kr/dc1aadc8b3d8d6971434 to your computer and use it in GitHub Desktop.
Save kr/dc1aadc8b3d8d6971434 to your computer and use it in GitHub Desktop.
windows input without echoing typed chars
package main
import (
"bufio"
"fmt"
"os"
"syscall"
"unsafe"
)
// input modes
const (
ENABLE_PROCESSED_INPUT = 1 << iota
ENABLE_LINE_INPUT
ENABLE_ECHO_INPUT
ENABLE_WINDOW_INPUT
ENABLE_MOUSE_INPUT
ENABLE_INSERT_MODE
ENABLE_QUICK_EDIT_MODE
ENABLE_EXTENDED_FLAGS
)
// output modes
const (
ENABLE_PROCESSED_OUTPUT = 1 << iota
ENABLE_WRAP_AT_EOL_OUTPUT
)
func abort(funcname string, err error) {
panic(funcname + " failed: " + err.Error())
}
var kernel32 = mustLoadLibrary("kernel32.dll")
var (
addrGetConsoleMode = mustGetProcAddress(kernel32, "GetConsoleMode")
addrSetConsoleMode = mustGetProcAddress(kernel32, "SetConsoleMode")
)
func main() {
mode, err := getConsoleMode(os.Stdin)
if err != nil {
panic(err)
}
mode &= ^ENABLE_ECHO_INPUT
err = setConsoleMode(os.Stdin, mode)
if err != nil {
panic(err)
}
os.Stdout.Write([]byte("noecho: "))
b := bufio.NewReader(os.Stdin)
line, err := b.ReadBytes('\n')
os.Stdout.Write([]byte{'\n'})
if err != nil {
panic(err)
}
fmt.Printf("got %q\n", string(line))
}
func getConsoleMode(f *os.File) (mode int32, err error) {
p := uintptr(unsafe.Pointer(&mode))
_, _, e := syscall.Syscall(addrGetConsoleMode, 2, f.Fd(), p, 0)
if e != 0 {
err = e
}
return
}
func setConsoleMode(f *os.File, mode int32) error {
_, _, e := syscall.Syscall(addrSetConsoleMode, 2, f.Fd(), uintptr(mode), 0)
if e != 0 {
return e
}
return nil
}
func mustLoadLibrary(name string) syscall.Handle {
h, err := syscall.LoadLibrary("kernel32.dll")
if err != nil {
abort("LoadLibrary", err)
}
return h
}
func mustGetProcAddress(h syscall.Handle, name string) uintptr {
addr, err := syscall.GetProcAddress(h, name)
if err != nil {
abort("GetProcAddress", err)
}
return addr
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment