commit 886fca3fd657d09cec2431fa1281478b904c8e28
parent 0fa5a3e5bb40b92e4141bdfcc37603805d520923
Author: FRIGN <dev@frign.de>
Date: Mon, 7 Mar 2016 10:20:40 +0100
Support NUL containing lines in tail(1)
This was rather simple this time.
Diffstat:
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git 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
@@ -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;