func (l *lflagSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error { if value == 0 { termios.Lflag &^= l.Flag } else { termios.Lflag |= l.Flag } return SetAttr(pty, termios) }
// returns non-canonical mode term for keybind func rawModeTerm(term syscall.Termios) syscall.Termios { term.Iflag &= syscall.IGNCR // ignore received CR term.Lflag ^= syscall.ICANON // disable canonical mode term.Lflag ^= syscall.ECHO // disable echo of input term.Lflag ^= syscall.ISIG // disable signal term.Cc[syscall.VMIN] = 1 // number of bytes to read() term.Cc[syscall.VTIME] = 0 // timeout of read() return term }
// Cfmakeraw modifies attr for raw mode. func Cfmakeraw(attr *syscall.Termios) { attr.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON attr.Oflag &^= syscall.OPOST attr.Cflag &^= syscall.CSIZE | syscall.PARENB attr.Cflag |= syscall.CS8 attr.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG attr.Cc[syscall.VMIN] = 1 attr.Cc[syscall.VTIME] = 0 }
func OpenSerial(device string, baud uint) (s *serial, err error) { myBaud := getBaud(baud) if myBaud == 0 { err = errInvalidBaud return } fd, err := syscall.Open( device, os.O_RDWR|syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY|syscall.O_NONBLOCK, 0666) if err != nil { return } defer func() { if err != nil { syscall.Close(fd) } }() term := syscall.Termios{} if err = sys.Ioctl(uintptr(fd), syscall.TCGETS, uintptr(unsafe.Pointer(&term))); err != nil { return } term.Ispeed = myBaud term.Ospeed = myBaud term.Cflag |= (syscall.CLOCAL | syscall.CREAD) term.Cflag = uint32(int32(term.Cflag) & ^syscall.PARENB & ^syscall.CSTOPB & ^syscall.CSIZE) term.Cflag |= syscall.CS8 term.Lflag = uint32(int32(term.Lflag) & ^(syscall.ICANON | syscall.ECHO | syscall.ECHOE | syscall.ISIG)) term.Oflag = uint32(int32(term.Oflag) & ^syscall.OPOST) term.Cc[syscall.VMIN] = 0 term.Cc[syscall.VTIME] = 100 if err = sys.Ioctl(uintptr(fd), syscall.TCSETS, uintptr(unsafe.Pointer(&term))); err != nil { return } status := 0 if err = sys.Ioctl(uintptr(fd), syscall.TIOCMGET, uintptr(unsafe.Pointer(&status))); err != nil { return } status |= syscall.TIOCM_DTR | syscall.TIOCM_RTS if err = sys.Ioctl(uintptr(fd), syscall.TIOCMSET, uintptr(unsafe.Pointer(&status))); err != nil { return } s = &serial{uintptr(fd)} runtime.SetFinalizer(s, func(this *serial) { this.Close() }) return }
// disableEcho disables terminal echoing, which simplifies parsing by // not having our inputs mixed into it. func (b *Bash) disableEcho() error { var termios syscall.Termios _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.pty.Fd(), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&termios))) if errno != 0 { return errno } termios.Lflag &^= syscall.ECHO _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, b.pty.Fd(), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&termios))) if errno != 0 { return errno } return nil }
func setRawMode(settings *syscall.Termios) { // Set local mode settings.Cflag |= termiosMask(syscall.CREAD | syscall.CLOCAL) // Set raw mode settings.Lflag &= ^termiosMask(syscall.ICANON | syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL | syscall.ECHOCTL | syscall.ECHOPRT | syscall.ECHOKE | syscall.ISIG | syscall.IEXTEN) settings.Iflag &= ^termiosMask(syscall.IXON | syscall.IXOFF | syscall.IXANY | syscall.INPCK | syscall.IGNPAR | syscall.PARMRK | syscall.ISTRIP | syscall.IGNBRK | syscall.BRKINT | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | tcIUCLC) settings.Oflag &= ^termiosMask(syscall.OPOST) // Block reads until at least one char is available (no timeout) settings.Cc[syscall.VMIN] = 1 settings.Cc[syscall.VTIME] = 0 }
func ReadPassword(fd uintptr) (string, error) { var termios, oldState syscall.Termios if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, fd, TCGETS, uintptr(unsafe.Pointer(&termios)), 0, 0, 0); e == 0 { oldState = termios termios.Lflag &^= syscall.ECHO if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, fd, TCSETS, uintptr(unsafe.Pointer(&termios)), 0, 0, 0); e == 0 { } // Restoring after reading the password defer syscall.Syscall6(syscall.SYS_IOCTL, fd, TCSETS, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) // Restoring on SIGINT sigChan := make(chan os.Signal, 1) go func(c chan os.Signal, t syscall.Termios, fd uintptr) { if _, ok := <-c; ok { syscall.Syscall6(syscall.SYS_IOCTL, fd, TCSETS, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) os.Exit(1) } }(sigChan, oldState, fd) defer close(sigChan) signal.Notify(sigChan, syscall.SIGINT) } var buf [16]byte var pass []byte for { n, err := syscall.Read(int(fd), buf[:]) if n == 0 { break } if err != nil { return "", err } for n > 0 && (buf[n-1] == '\n' || buf[n-1] == '\r') { n-- } pass = append(pass, buf[:n]...) if n < len(buf) { break } } return string(pass), nil }
func setRawMode(settings *syscall.Termios, mode *Mode) { // Set local mode settings.Cflag |= termiosMask(syscall.CREAD | syscall.CLOCAL) // Set raw mode settings.Lflag &= ^termiosMask(syscall.ICANON | syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL | syscall.ECHOCTL | syscall.ECHOPRT | syscall.ECHOKE | syscall.ISIG | syscall.IEXTEN) settings.Iflag &= ^termiosMask(syscall.IXON | syscall.IXOFF | syscall.IXANY | syscall.INPCK | syscall.IGNPAR | syscall.PARMRK | syscall.ISTRIP | syscall.IGNBRK | syscall.BRKINT | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | tc_IUCLC) settings.Oflag &= ^termiosMask(syscall.OPOST) if mode.Vmin == 0 && mode.Vtimeout == 0 { // Switch to default mode // Block reads until at least one char is available (no timeout) mode.Vmin = 1 } settings.Cc[syscall.VMIN] = mode.Vmin settings.Cc[syscall.VTIME] = mode.Vtimeout }
// Cfmakecbreak modifies attr for cbreak mode. func Cfmakecbreak(attr *syscall.Termios) { attr.Lflag &^= syscall.ECHO | syscall.ICANON attr.Cc[syscall.VMIN] = 1 attr.Cc[syscall.VTIME] = 0 }