commit 886fca3fd657d09cec2431fa1281478b904c8e28
Author:     FRIGN <[email protected]>
AuthorDate: Mon Mar 7 10:20:40 2016 +0100
Commit:     sin <[email protected]>
CommitDate: Thu Mar 10 08:48:09 2016 +0000

    Support NUL containing lines in tail(1)
    
    This was rather simple this time.

diff --git a/README b/README
index 8f553a6..f814284 100644
--- a/README
+++ b/README
@@ -84,7 +84,7 @@ The following tools are implemented:
 0=*|x sponge          .
 0#*|o strings         .
 0=*|x sync            .
- =*|o tail            .
+0=*|o tail            .
 0=*|x tar             .
 0=*|o tee             .
 0=*|o test            .
diff --git a/tail.c b/tail.c
index 4ab5fde..711707f 100644
--- a/tail.c
+++ b/tail.c
@@ -26,7 +26,7 @@ dropinit(FILE *fp, const char *str, size_t n)
                        if (len > 0 && buf[len - 1] == '\n')
                                i++;
        } else {
-               while (i < n && (len = efgetrune(&r, fp, str)))
+               while (i < n && efgetrune(&r, fp, str))
                        i++;
        }
        free(buf);
@@ -37,8 +37,9 @@ static void
 taketail(FILE *fp, const char *str, size_t n)
 {
        Rune *r = NULL;
-       char **ring = NULL;
+       struct line *ring = NULL;
        size_t i, j, *size = NULL;
+       ssize_t len;
        int seenln = 0;
 
        if (!n)
@@ -48,8 +49,11 @@ 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; seenln = 1)
+               for (i = j = 0; (len = getline(&ring[i].data,
+                    &size[i], fp)) > 0; seenln = 1) {
+                       ring[i].len = len;
                        i = j = (i + 1) % n;
+               }
        } else {
                r = ecalloc(n, sizeof(*r));
 
@@ -60,9 +64,9 @@ taketail(FILE *fp, const char *str, size_t n)
                eprintf("%s: read error:", str);
 
        do {
-               if (seenln && ring && ring[j]) {
-                       fputs(ring[j], stdout);
-                       free(ring[j]);
+               if (seenln && ring && ring[j].data) {
+                       fwrite(ring[j].data, 1, ring[j].len, stdout);
+                       free(ring[j].data);
                } else if (r) {
                        efputrune(&r[j], stdout, "<stdout>");
                }
@@ -97,7 +101,8 @@ main(int argc, char *argv[])
        case 'n':
                mode = ARGC();
                numstr = EARGF(usage());
-               n = MIN(llabs(estrtonum(numstr, LLONG_MIN + 1, MIN(LLONG_MAX, 
SIZE_MAX))), SIZE_MAX);
+               n = MIN(llabs(estrtonum(numstr, LLONG_MIN + 1,
+                                       MIN(LLONG_MAX, SIZE_MAX))), SIZE_MAX);
                if (strchr(numstr, '+'))
                        tail = dropinit;
                break;

Reply via email to