From a63b28875ff5b7f52b2c41992656afac36c66a34 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 27 Jul 2017 13:53:59 +0200 Subject: [PATCH] linux: detect port disconnection during Read See https://stackoverflow.com/a/34945814/1655275 > pselect signals that file descriptor is ready and > ioctl(fd, FIONREAD, &len) returns zero len. Failure to detect this condition has been revealed by the testsuite: === RUN TestDisconnectingPortDetection 2017/07/27 13:56:37 PR - Connecting to Probe 2017/07/27 13:56:37 > Searching for port 2341:8037 2017/07/27 13:56:37 Detected port '/dev/ttyACM0' 2341:8037 2017/07/27 13:56:37 Using '/dev/ttyACM0' 2017/07/27 13:56:37 Starting test (timeout 20s) 2017/07/27 13:56:37 PR - Turn ON target 2017/07/27 13:56:37 TR - Connecting to Target 2017/07/27 13:56:37 > Searching for port 2341:8036 2017/07/27 13:56:37 Detected port '/dev/ttyACM0' 2341:8037 [...cut...] 2017/07/27 13:56:46 > Searching for port 2341:8036 2017/07/27 13:56:46 Detected port '/dev/ttyACM0' 2341:8037 2017/07/27 13:56:46 Detected port '/dev/ttyACM1' 2341:8036 2017/07/27 13:56:46 Using '/dev/ttyACM1' 2017/07/27 13:56:46 T2 - Make a Read call 2017/07/27 13:56:46 T1 - Delay 200ms before disconnecting target 2017/07/27 13:56:46 T1 - Disconnect target 2017/07/27 13:56:46 PR - Turn OFF target 2017/07/27 13:56:46 T2 - Read returned: n=0 err=nil --- FAIL: TestDisconnectingPortDetection (9.18s) Error Trace: serial_test.go:100 Error: An error is expected but got nil. %s Messages: Read returned no errors this commit fix the problem above. --- serial_unix.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/serial_unix.go b/serial_unix.go index f9e887c..c921389 100644 --- a/serial_unix.go +++ b/serial_unix.go @@ -77,6 +77,12 @@ func (port *unixPort) Read(p []byte) (int, error) { if err == unix.EINTR { continue } + // Linux: when the port is disconnected during a read operation + // the port is left in a "readable with zero-length-data" state. + // https://stackoverflow.com/a/34945814/1655275 + if n == 0 && err == nil { + return 0, &PortError{code: PortClosed} + } if n < 0 { // Do not return -1 unix errors n = 0 }