Exemplo n.º 1
0
func setTermSettingsCtsRts(enable bool, settings *syscall.Termios) {
	if enable {
		settings.Cflag |= termiosMask(tcCRTSCTS)
	} else {
		settings.Cflag &= ^termiosMask(tcCRTSCTS)
	}
}
Exemplo n.º 2
0
// Configure configures f as a 8N1 serial port with the specified baudrate.
func Configure(f fder, baudrate uint32) error {
	var termios syscall.Termios
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(f.Fd()), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&termios))); err != 0 {
		return err
	}

	termios.Ispeed = baudrate
	termios.Ospeed = baudrate
	termios.Cflag &^= CBAUD
	termios.Cflag &^= CBAUDEX
	termios.Cflag |= baudrate

	// set 8N1
	termios.Cflag &^= syscall.PARENB
	termios.Cflag &^= syscall.CSTOPB
	termios.Cflag &^= syscall.CSIZE
	termios.Cflag |= syscall.CS8

	// Local connection, no modem control
	termios.Cflag |= (syscall.CLOCAL | syscall.CREAD)
	// Disable hardware flow control
	termios.Cflag &^= CRTSCTS
	// Block on a zero read (instead of returning EOF)
	termios.Cc[syscall.VMIN] = 1

	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(f.Fd()), syscall.TCSETS, uintptr(unsafe.Pointer(&termios))); err != 0 {
		return err
	}
	return nil
}
Exemplo n.º 3
0
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)
}
Exemplo n.º 4
0
func (i *iflagSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error {
	if value == 0 {
		termios.Iflag &^= i.Flag
	} else {
		termios.Iflag |= i.Flag
	}
	return TcSetAttr(pty, termios)
}
Exemplo n.º 5
0
func setTermSettingsDataBits(bits int, settings *syscall.Termios) error {
	databits, ok := databitsMap[bits]
	if !ok {
		return &SerialPortError{code: ERROR_INVALID_PORT_DATA_BITS}
	}
	settings.Cflag &= ^termiosMask(syscall.CSIZE)
	settings.Cflag |= termiosMask(databits)
	return nil
}
Exemplo n.º 6
0
Arquivo: termios.go Projeto: pkg/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
}
Exemplo n.º 7
0
func setTermSettingsDataBits(bits int, settings *syscall.Termios) error {
	databits, ok := databitsMap[bits]
	if !ok {
		return &PortError{code: InvalidDataBits}
	}
	settings.Cflag &= ^termiosMask(syscall.CSIZE)
	settings.Cflag |= termiosMask(databits)
	return nil
}
Exemplo n.º 8
0
// 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
}
Exemplo n.º 9
0
func setTermSettingsStopBits(bits StopBits, settings *syscall.Termios) error {
	switch bits {
	case OneStopBit:
		settings.Cflag &= ^termiosMask(syscall.CSTOPB)
	case OnePointFiveStopBits, TwoStopBits:
		settings.Cflag |= termiosMask(syscall.CSTOPB)
	}
	return nil
}
Exemplo n.º 10
0
func setTermSettingsStopBits(bits StopBits, settings *syscall.Termios) error {
	switch bits {
	case STOPBITS_ONE:
		settings.Cflag &= ^termiosMask(syscall.CSTOPB)
	case STOPBITS_ONEPOINTFIVE, STOPBITS_TWO:
		settings.Cflag |= termiosMask(syscall.CSTOPB)
	}
	return nil
}
Exemplo n.º 11
0
// 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
}
Exemplo n.º 12
0
func (c *cflagSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error {
	switch c.Flag {
	// CSIZE is a field
	case syscall.CS7, syscall.CS8:
		termios.Cflag &^= syscall.CSIZE
		termios.Cflag |= c.Flag
	default:
		if value == 0 {
			termios.Cflag &^= c.Flag
		} else {
			termios.Cflag |= c.Flag
		}
	}

	return SetAttr(pty, termios)
}
Exemplo n.º 13
0
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
}
Exemplo n.º 14
0
func setTermSettingsBaudrate(speed int, settings *syscall.Termios) error {
	baudrate, ok := baudrateMap[speed]
	if !ok {
		return &PortError{code: InvalidSpeed}
	}
	// revert old baudrate
	var BAUDMASK uint
	for _, rate := range baudrateMap {
		BAUDMASK |= rate
	}
	settings.Cflag &= ^termiosMask(BAUDMASK)
	// set new baudrate
	settings.Cflag |= termiosMask(baudrate)
	settings.Ispeed = termiosMask(baudrate)
	settings.Ospeed = termiosMask(baudrate)
	return nil
}
Exemplo n.º 15
0
// saneTerminal sets the necessary tty_ioctl(4)s to ensure that a pty pair
// created by us acts normally. In particular, a not-very-well-known default of
// Linux unix98 ptys is that they have +onlcr by default. While this isn't a
// problem for terminal emulators, because we relay data from the terminal we
// also relay that funky line discipline.
func saneTerminal(terminal *os.File) error {
	// Go doesn't have a wrapper for any of the termios ioctls.
	var termios syscall.Termios

	if err := ioctl(terminal.Fd(), syscall.TCGETS, uintptr(unsafe.Pointer(&termios))); err != nil {
		return fmt.Errorf("ioctl(tty, tcgets): %s", err.Error())
	}

	// Set -onlcr so we don't have to deal with \r.
	termios.Oflag &^= syscall.ONLCR

	if err := ioctl(terminal.Fd(), syscall.TCSETS, uintptr(unsafe.Pointer(&termios))); err != nil {
		return fmt.Errorf("ioctl(tty, tcsets): %s", err.Error())
	}

	return nil
}
Exemplo n.º 16
0
func setTermSettingsBaudrate(speed int, settings *syscall.Termios) error {
	baudrate, ok := baudrateMap[speed]
	if !ok {
		return &SerialPortError{code: ERROR_INVALID_PORT_SPEED}
	}
	// revert old baudrate
	BAUDMASK := 0
	for _, rate := range baudrateMap {
		BAUDMASK |= rate
	}
	settings.Cflag &= ^termiosMask(BAUDMASK)
	// set new baudrate
	settings.Cflag |= termiosMask(baudrate)
	settings.Ispeed = termiosMask(baudrate)
	settings.Ospeed = termiosMask(baudrate)
	return nil
}
Exemplo n.º 17
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
}
Exemplo n.º 18
0
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
}
Exemplo n.º 19
0
func (s *Screen) Init() error {
	var err error
	ttyIn, err = os.OpenFile("/dev/tty", os.O_RDWR, 0666)
	if err != nil {
		return err
	}
	ttyOut, err = os.OpenFile("/dev/tty", os.O_RDONLY, 0666)
	if err != nil {
		return err
	}

	orig = new(syscall.Termios)
	err = tcgetattr(ttyIn.Fd(), orig)
	if err != nil {
		return err
	}

	tios := new(syscall.Termios)
	*tios = *orig
	tios.Iflag &= ^uint32(syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG)
	tios.Iflag &= ^uint32(syscall.BRKINT | syscall.ICRNL | syscall.ISTRIP | syscall.IXON)
	tios.Cflag &= ^uint32(syscall.CSIZE | syscall.PARENB)
	tios.Cflag |= syscall.CS8
	tios.Oflag &= ^uint32(syscall.OPOST)
	tios.Cc[syscall.VMIN] = 1
	tios.Cc[syscall.VTIME] = 0
	err = tcsetattr(ttyIn.Fd(), tios)
	if err != nil {
		return err
	}
	s.HideCursor()
	s.Clear()
	return nil
}
Exemplo n.º 20
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
}
Exemplo n.º 21
0
// Open a connection with a read timeout.
func (connection *Connection) Open(timeout uint8) error {

	var err error

	// The serial port is basically a file we are writing to and reading from.
	// 	O_RDWR allows the program to read and write the file.
	// 	O_NOCTTY prevents the device from controlling the terminal.
	// 	O_NONBLOCK prevents the system from blocking for a long time.
	connection.f, err = os.OpenFile(connection.Port,
		syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666)
	if err != nil {
		return err
	}

	// Close the file on error occurrence.
	defer func() {
		if err != nil && connection.f != nil {
			connection.f.Close()
		}
	}()

	// Create a plain termios, which allows the program to execute
	// input/output operations.
	termios := syscall.Termios{}

	// Setup the baud rate in the termios structure.
	baudrate := baudrates[connection.Baud]

	termios.Cflag |= baudrate
	termios.Ispeed = baudrate
	termios.Ospeed = baudrate

	// Setup stop bits in the termios structure.
	switch connection.StopBit {
	case StopBit1:
		termios.Cflag &^= syscall.CSTOPB // CSTOPB = 0x40
	case StopBit2:
		termios.Cflag |= syscall.CSTOPB
	default:
		return errStopBit
	}

	// Setup data bits in the termios structure.
	databit := databits[connection.DataBit]
	termios.Cflag |= databit

	// Setup parity in the termios structure.
	switch connection.Parity {
	case ParityNone:
		termios.Cflag &^= syscall.PARENB // PARENB = 0x100
	case ParityEven:
		termios.Cflag |= syscall.PARENB
	case ParityOdd:
		termios.Cflag |= syscall.PARENB
		termios.Cflag |= syscall.PARODD // PARODD = 0x200
	default:
		return errParity
	}

	// // set blocking / non-blocking read
	vmin := uint8(0)
	if timeout == 0 {
		vmin = 1
	}

	// Attach min bytes and timeout to the termios structure.
	termios.Cc = [32]uint8{
		syscall.VMIN:  vmin,    // min bytes per transfer
		syscall.VTIME: timeout, // actual read timeout in deciseconds
	}

	// Execute IOCTL with the modified termios structure to apply the changes.
	if _, _, errno := syscall.Syscall6(
		// device-specific input/output operations
		syscall.SYS_IOCTL,
		// open file descriptor
		uintptr(connection.f.Fd()),
		// a request code number to set the current serial port settings
		uintptr(syscall.TCSETS),
		//TODO: it looks like syscall.TCSETS is not available under
		// freebsd and darwin. Is this a bug?
		uintptr(unsafe.Pointer(&termios)), // a pointer to the termios structure
		0,
		0,
		0,
	); errno != 0 {
		return errno
	}

	connection.isOpen = true
	return nil
}
Exemplo n.º 22
0
Arquivo: termios.go Projeto: pkg/term
// 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
}
Exemplo n.º 23
0
func setTermSettingsParity(parity Parity, settings *syscall.Termios) error {
	switch parity {
	case PARITY_NONE:
		settings.Cflag &= ^termiosMask(syscall.PARENB | syscall.PARODD | tc_CMSPAR)
		settings.Iflag &= ^termiosMask(syscall.INPCK)
	case PARITY_ODD:
		settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD)
		settings.Cflag &= ^termiosMask(tc_CMSPAR)
		settings.Iflag |= termiosMask(syscall.INPCK)
	case PARITY_EVEN:
		settings.Cflag &= ^termiosMask(syscall.PARODD | tc_CMSPAR)
		settings.Cflag |= termiosMask(syscall.PARENB)
		settings.Iflag |= termiosMask(syscall.INPCK)
	case PARITY_MARK:
		settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD | tc_CMSPAR)
		settings.Iflag |= termiosMask(syscall.INPCK)
	case PARITY_SPACE:
		settings.Cflag &= ^termiosMask(syscall.PARODD)
		settings.Cflag |= termiosMask(syscall.PARENB | tc_CMSPAR)
		settings.Iflag |= termiosMask(syscall.INPCK)
	}
	return nil
}
Exemplo n.º 24
-1
func setTermSettingsParity(parity Parity, settings *syscall.Termios) error {
	switch parity {
	case NoParity:
		settings.Cflag &= ^termiosMask(syscall.PARENB | syscall.PARODD | tcCMSPAR)
		settings.Iflag &= ^termiosMask(syscall.INPCK)
	case OddParity:
		settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD)
		settings.Cflag &= ^termiosMask(tcCMSPAR)
		settings.Iflag |= termiosMask(syscall.INPCK)
	case EvenParity:
		settings.Cflag &= ^termiosMask(syscall.PARODD | tcCMSPAR)
		settings.Cflag |= termiosMask(syscall.PARENB)
		settings.Iflag |= termiosMask(syscall.INPCK)
	case MarkParity:
		settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD | tcCMSPAR)
		settings.Iflag |= termiosMask(syscall.INPCK)
	case SpaceParity:
		settings.Cflag &= ^termiosMask(syscall.PARODD)
		settings.Cflag |= termiosMask(syscall.PARENB | tcCMSPAR)
		settings.Iflag |= termiosMask(syscall.INPCK)
	}
	return nil
}