func (d *dev) Drain() (err error) { err = sys.IoctlTermios(d.Fd(), sys.TCSETSW, &d.tsav) // drain and set parameters if err != nil { err = d.error("drain", err) } return }
// Open a local serial port. // Inictl is an optional string containing one ore more commands in Ctl() style func Open(filename string, inictl string) (port Port, err error) { var file *os.File // NONBLOCK prevents Open from blocking // until DCD is asserted from modem if file, err = os.OpenFile(filename, os.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0); err != nil { return } p := new(dev) p.File = file p.name = filename p.encaps = p fd := file.Fd() err = setBlocking(fd) if err != nil { err = p.error("set blocking", err) } t := &p.t if err = sys.IoctlTermios(fd, sys.TCGETS, t); err != nil { err = p.error("get term attr", err) return } p.tOrig = p.t p.tsav = p.t t.Cflag |= sys.CLOCAL t.Lflag &^= sys.ICANON | sys.ECHO | sys.ISIG | sys.IEXTEN t.Iflag &^= sys.BRKINT | sys.ICRNL | sys.INPCK | sys.ISTRIP | sys.IXON t.Iflag |= sys.IGNPAR t.Oflag &^= sys.OPOST // timeout 1/10s after the last byte (at least one) has been read t.Cc[sys.VMIN] = 1 t.Cc[sys.VTIME] = 1 if err = p.Ctl(initDefault, inictl); err != nil { return } port = p return }
func (d *dev) updateCtl() (err error) { if d.inCtl { return } t := &d.t tsav := &d.tsav if t.Cflag == tsav.Cflag && t.Lflag == tsav.Lflag && t.Oflag == tsav.Oflag && t.Cc[sys.VTIME] == tsav.Cc[sys.VTIME] && t.Cc[sys.VMIN] == tsav.Cc[sys.VMIN] { return } if err = sys.IoctlTermios(d.Fd(), sys.TCSETSW, t); err == nil { // drain and set parameters d.tsav = d.t // It seems changing parameters also resets DTR/RTS lines; // put in the previously requested states again: d.SetRts(d.rts) d.SetDtr(d.dtr) } return }
func (p *dev) Close() error { sys.IoctlTermios(p.Fd(), sys.TCSETSW, &p.tOrig) return p.hw.Close() }