From 26650049c0f90552b9c7a6fd8771c90e86132c4f Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Wed, 5 Oct 2016 13:17:14 -0300 Subject: [PATCH] AP_HAL_Linux: UARTDriver: fix writting/reading with failures When the buffer wraps and we do it in 2 steps, we can't actually do the second part if it fails or if we wrote less bytes than we intended, otherwise we will corrupt the data being sent. --- libraries/AP_HAL_Linux/UARTDriver.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/libraries/AP_HAL_Linux/UARTDriver.cpp b/libraries/AP_HAL_Linux/UARTDriver.cpp index d25d6b0933..8d0e8f42c0 100644 --- a/libraries/AP_HAL_Linux/UARTDriver.cpp +++ b/libraries/AP_HAL_Linux/UARTDriver.cpp @@ -429,8 +429,15 @@ bool UARTDriver::_write_pending_bytes(void) const auto n_vec = _writebuf.peekiovec(vec, n); for (int i = 0; i < n_vec; i++) { ret = _write_fd(vec[i].data, (uint16_t)vec[i].len); - if (ret > 0) - _writebuf.advance(ret); + if (ret < 0) { + break; + } + _writebuf.advance(ret); + + /* We wrote less than we asked for, stop */ + if ((unsigned)ret != vec[i].len) { + break; + } } } } @@ -461,11 +468,15 @@ void UARTDriver::_timer_tick(void) const auto n_vec = _readbuf.reserve(vec, _readbuf.space()); for (int i = 0; i < n_vec; i++) { ret = _read_fd(vec[i].data, vec[i].len); - if (ret < 0) + if (ret < 0) { break; + } _readbuf.commit((unsigned)ret); - if ((unsigned)ret < vec[i].len) + + /* stop reading as we read less than we asked for */ + if ((unsigned)ret < vec[i].len) { break; + } } _in_timer = false;