File fix-infinite-loop.patch of Package indi
From 8d123d976aa0e68fbc0918db1119282a9f071102 Mon Sep 17 00:00:00 2001
From: Jasem Mutlaq <mutlaqja@ikarustech.com>
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);