I'm working with github.com/tarm/serial
to interface with some serial instrumentation. In development, I'm working with the /dev/ttyp0
and /dev/ptyp0
pair, where my go process connects to one and I use screen
to connect to the other. I've written a function that, combined with serial.Config.ReadTimeout
, reads for up to ReadTimeout
or a given byte sequence is received. That function is:
func readToTermination(s serial.Port, termination []byte, rate time.Duration) []byte {
var out []byte
lterm := len(termination)
for {
buf := make([]byte, 128)
n, _ := s.Read(buf)
out = append(out, buf[:n]...)
l := len(out)
if l >= lterm {
if bytes.Compare(out[l-lterm:], termination) == 0 {
break
}
}
time.Sleep(rate)
}
return out
}
This avoids burning up CPU cycles doing nothing with a debounce. When I test with termination = []byte("
")
and screen, the break
never triggers because it turns into []byte{97, 11}
(two distinct elements, something like screen flushing after each keystroke). On the other hand, if I do something like echo "foo" > /dev/ptyp0
, the break triggers correctly. Echo implicitly seems to be sending a
, or the closing of the connection does so. I see
for echo foo
and
for echo "foo
"
.
So my question is:
(1) why is there a difference in behavior here?
(2) how do I get the behavior I really am after with a carriage return for the termination? Perhaps I should use EOT instead? A human will never be typing into this directly.