From d353cdb52f98e27afd74c51b844ead3e6616d1bb Mon Sep 17 00:00:00 2001
From: Jeff Long <willcode4@gmail.com>
Date: Fri, 15 Jan 2021 06:49:55 -0500
Subject: File Source: handle EOF for non-seekable files

Based on original PR by esqt.

Signed-off-by: Jeff Long <willcode4@gmail.com>
---
 gr-blocks/lib/file_source_impl.cc | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

(limited to 'gr-blocks/lib/file_source_impl.cc')

diff --git a/gr-blocks/lib/file_source_impl.cc b/gr-blocks/lib/file_source_impl.cc
index 7d5f902516..b6adc50c52 100644
--- a/gr-blocks/lib/file_source_impl.cc
+++ b/gr-blocks/lib/file_source_impl.cc
@@ -270,8 +270,9 @@ int file_source_impl::work(int noutput_items,
     gr::thread::scoped_lock lock(fp_mutex); // hold for the rest of this function
 
     // No items remaining - all done
-    if (d_items_remaining == 0)
+    if (d_items_remaining == 0) {
         return WORK_DONE;
+    }
 
     while (size) {
 
@@ -287,13 +288,21 @@ int file_source_impl::work(int noutput_items,
 
         uint64_t nitems_to_read = std::min(size, d_items_remaining);
 
-        // Since the bounds of the file are known, unexpected nitems is an error
-        if (nitems_to_read != fread(o, d_itemsize, nitems_to_read, (FILE*)d_fp))
+        size_t nitems_read = fread(o, d_itemsize, nitems_to_read, (FILE*)d_fp);
+        if (nitems_to_read != nitems_read) {
+            // Size of non-seekable files is unknown. EOF is normal.
+            if (!d_seekable && feof((FILE*)d_fp)) {
+                size -= nitems_read;
+                d_items_remaining = 0;
+                break;
+            }
+
             throw std::runtime_error("fread error");
+        }
 
-        size -= nitems_to_read;
-        d_items_remaining -= nitems_to_read;
-        o += nitems_to_read * d_itemsize;
+        size -= nitems_read;
+        d_items_remaining -= nitems_read;
+        o += nitems_read * d_itemsize;
 
         // Ran out of items ("EOF")
         if (d_items_remaining == 0) {
-- 
cgit v1.2.3