From 8d123d976aa0e68fbc0918db1119282a9f071102 Mon Sep 17 00:00:00 2001 From: Jasem Mutlaq Date: Mon, 15 Dec 2025 17:52:39 +0300 Subject: [PATCH] Fix infinite loop when read=0 --- libs/indibase/connectionplugins/ttybase.cpp | 34 +++++++++++++++++++++ libs/indicore/indicom.c | 18 +++++++++++ 2 files changed, 52 insertions(+) diff --git a/libs/indibase/connectionplugins/ttybase.cpp b/libs/indibase/connectionplugins/ttybase.cpp index e6247782bd..bfee729ce1 100644 --- a/libs/indibase/connectionplugins/ttybase.cpp +++ b/libs/indibase/connectionplugins/ttybase.cpp @@ -166,6 +166,8 @@ TTYBase::TTY_RESPONSE TTYBase::read(uint8_t *buffer, uint32_t nbytes, uint8_t ti uint32_t numBytesToRead = nbytes; int bytesRead = 0; + int zero_read_count = 0; + const int MAX_ZERO_READS = 3; TTY_RESPONSE timeoutResponse = TTY_OK; *nbytes_read = 0; @@ -185,6 +187,21 @@ TTYBase::TTY_RESPONSE TTYBase::read(uint8_t *buffer, uint32_t nbytes, uint8_t ti if (bytesRead < 0) return TTY_READ_ERROR; + if (bytesRead == 0) + { + zero_read_count++; + if (zero_read_count >= MAX_ZERO_READS) + { + DEBUGFDEVICE(m_DriverName, m_DebugChannel, + "%s: Device not responding (zero bytes read %d times)", __FUNCTION__, MAX_ZERO_READS); + return TTY_READ_ERROR; + } + usleep(10000); // 10ms delay before retry + continue; + } + + zero_read_count = 0; // Reset counter on successful read + DEBUGFDEVICE(m_DriverName, m_DebugChannel, "%d bytes read and %d bytes remaining...", bytesRead, numBytesToRead - bytesRead); for (uint32_t i = *nbytes_read; i < (*nbytes_read + bytesRead); i++) @@ -210,6 +227,8 @@ TTYBase::TTY_RESPONSE TTYBase::readSection(uint8_t *buffer, uint32_t nsize, uint return TTY_ERRNO; int bytesRead = 0; + int zero_read_count = 0; + const int MAX_ZERO_READS = 3; TTY_RESPONSE timeoutResponse = TTY_OK; *nbytes_read = 0; memset(buffer, 0, nsize); @@ -230,6 +249,21 @@ TTYBase::TTY_RESPONSE TTYBase::readSection(uint8_t *buffer, uint32_t nsize, uint if (bytesRead < 0) return TTY_READ_ERROR; + if (bytesRead == 0) + { + zero_read_count++; + if (zero_read_count >= MAX_ZERO_READS) + { + DEBUGFDEVICE(m_DriverName, m_DebugChannel, + "%s: Device not responding (zero bytes read %d times)", __FUNCTION__, MAX_ZERO_READS); + return TTY_READ_ERROR; + } + usleep(10000); // 10ms delay before retry + continue; + } + + zero_read_count = 0; // Reset counter on successful read + DEBUGFDEVICE(m_DriverName, m_DebugChannel, "%s: buffer[%d]=%#X (%c)", __FUNCTION__, (*nbytes_read), *read_char, *read_char); (*nbytes_read)++; diff --git a/libs/indicore/indicom.c b/libs/indicore/indicom.c index 529db938db..f42e618058 100644 --- a/libs/indicore/indicom.c +++ b/libs/indicore/indicom.c @@ -597,6 +597,9 @@ int tty_read_expanded(int fd, char *buf, int nbytes, long timeout_seconds, long buffer = geminiBuffer; } + int zero_read_count = 0; + const int MAX_ZERO_READS = 3; + while (numBytesToRead > 0) { if ((err = tty_timeout_microseconds(fd, timeout_seconds, timeout_microseconds))) { @@ -610,6 +613,21 @@ int tty_read_expanded(int fd, char *buf, int nbytes, long timeout_seconds, long if (bytesRead < 0) return TTY_READ_ERROR; + if (bytesRead == 0) + { + zero_read_count++; + if (zero_read_count >= MAX_ZERO_READS) + { + if (tty_debug) + IDLog("%s: Device not responding (zero bytes read %d times)\n", __FUNCTION__, MAX_ZERO_READS); + return TTY_READ_ERROR; + } + usleep(10000); // 10ms delay before retry + continue; + } + + zero_read_count = 0; // Reset counter on successful read + if (tty_debug) { IDLog("%d bytes read and %d bytes remaining...\n", bytesRead, numBytesToRead - bytesRead);