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);
openSUSE Build Service is sponsored by