tc_solaris_cgo.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // +build solaris,cgo
  2. package term
  3. import (
  4. "syscall"
  5. "unsafe"
  6. "golang.org/x/sys/unix"
  7. )
  8. // #include <termios.h>
  9. import "C"
  10. // Termios is the Unix API for terminal I/O.
  11. // It is passthrough for unix.Termios in order to make it portable with
  12. // other platforms where it is not available or handled differently.
  13. type Termios unix.Termios
  14. // MakeRaw put the terminal connected to the given file descriptor into raw
  15. // mode and returns the previous state of the terminal so that it can be
  16. // restored.
  17. func MakeRaw(fd uintptr) (*State, error) {
  18. var oldState State
  19. if err := tcget(fd, &oldState.termios); err != 0 {
  20. return nil, err
  21. }
  22. newState := oldState.termios
  23. newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON | unix.IXANY)
  24. newState.Oflag &^= unix.OPOST
  25. newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
  26. newState.Cflag &^= (unix.CSIZE | unix.PARENB)
  27. newState.Cflag |= unix.CS8
  28. /*
  29. VMIN is the minimum number of characters that needs to be read in non-canonical mode for it to be returned
  30. Since VMIN is overloaded with another element in canonical mode when we switch modes it defaults to 4. It
  31. needs to be explicitly set to 1.
  32. */
  33. newState.Cc[C.VMIN] = 1
  34. newState.Cc[C.VTIME] = 0
  35. if err := tcset(fd, &newState); err != 0 {
  36. return nil, err
  37. }
  38. return &oldState, nil
  39. }
  40. func tcget(fd uintptr, p *Termios) syscall.Errno {
  41. ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
  42. if ret != 0 {
  43. return err.(syscall.Errno)
  44. }
  45. return 0
  46. }
  47. func tcset(fd uintptr, p *Termios) syscall.Errno {
  48. ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
  49. if ret != 0 {
  50. return err.(syscall.Errno)
  51. }
  52. return 0
  53. }