termios_linux.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. package term
  2. import (
  3. "syscall"
  4. "unsafe"
  5. )
  6. const (
  7. getTermios = syscall.TCGETS
  8. setTermios = syscall.TCSETS
  9. )
  10. type Termios struct {
  11. Iflag uint32
  12. Oflag uint32
  13. Cflag uint32
  14. Lflag uint32
  15. Cc [20]byte
  16. Ispeed uint32
  17. Ospeed uint32
  18. }
  19. // MakeRaw put the terminal connected to the given file descriptor into raw
  20. // mode and returns the previous state of the terminal so that it can be
  21. // restored.
  22. func MakeRaw(fd uintptr) (*State, error) {
  23. var oldState State
  24. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
  25. return nil, err
  26. }
  27. newState := oldState.termios
  28. newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON)
  29. newState.Oflag &^= syscall.OPOST
  30. newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
  31. newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
  32. newState.Cflag |= syscall.CS8
  33. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
  34. return nil, err
  35. }
  36. return &oldState, nil
  37. }