getline(3) expects newline-terminated input. While glibc's
implementation seems to catch unterminated input and zero the
buffer, other versions (notably musl's) do not.

This is a workaround. Garbage will still be read, but
not printed.
---
 tail.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tail.c b/tail.c
index 306bbc1..417289f 100644
--- a/tail.c
+++ b/tail.c
@@ -39,6 +39,7 @@ taketail(FILE *fp, const char *str, size_t n)
        Rune *r = NULL;
        char **ring = NULL;
        size_t i, j, *size = NULL;
+       int seenln = 0;
 
        if (!n)
                return;
@@ -47,7 +48,7 @@ taketail(FILE *fp, const char *str, size_t n)
                ring = ecalloc(n, sizeof(*ring));
                size = ecalloc(n, sizeof(*size));
 
-               for (i = j = 0; getline(ring + i, size + i, fp) > 0; )
+               for (i = j = 0; getline(ring + i, size + i, fp) > 0; seenln = 1)
                        i = j = (i + 1) % n;
        } else {
                r = ecalloc(n, sizeof(*r));
@@ -59,7 +60,7 @@ taketail(FILE *fp, const char *str, size_t n)
                eprintf("%s: read error:", str);
 
        do {
-               if (ring && ring[j]) {
+               if (seenln && ring && ring[j]) {
                        fputs(ring[j], stdout);
                        free(ring[j]);
                } else if (r) {
-- 
2.3.5


Reply via email to