Support NUL containing lines in tail(1)

This was rather simple this time.
This commit is contained in:
FRIGN 2016-03-07 10:20:40 +01:00 committed by sin
parent 0fa5a3e5bb
commit 886fca3fd6
2 changed files with 13 additions and 8 deletions

2
README
View File

@ -84,7 +84,7 @@ The following tools are implemented:
0=*|x sponge . 0=*|x sponge .
0#*|o strings . 0#*|o strings .
0=*|x sync . 0=*|x sync .
=*|o tail . 0=*|o tail .
0=*|x tar . 0=*|x tar .
0=*|o tee . 0=*|o tee .
0=*|o test . 0=*|o test .

19
tail.c
View File

@ -26,7 +26,7 @@ dropinit(FILE *fp, const char *str, size_t n)
if (len > 0 && buf[len - 1] == '\n') if (len > 0 && buf[len - 1] == '\n')
i++; i++;
} else { } else {
while (i < n && (len = efgetrune(&r, fp, str))) while (i < n && efgetrune(&r, fp, str))
i++; i++;
} }
free(buf); free(buf);
@ -37,8 +37,9 @@ static void
taketail(FILE *fp, const char *str, size_t n) taketail(FILE *fp, const char *str, size_t n)
{ {
Rune *r = NULL; Rune *r = NULL;
char **ring = NULL; struct line *ring = NULL;
size_t i, j, *size = NULL; size_t i, j, *size = NULL;
ssize_t len;
int seenln = 0; int seenln = 0;
if (!n) if (!n)
@ -48,8 +49,11 @@ taketail(FILE *fp, const char *str, size_t n)
ring = ecalloc(n, sizeof(*ring)); ring = ecalloc(n, sizeof(*ring));
size = ecalloc(n, sizeof(*size)); 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; i = j = (i + 1) % n;
}
} else { } else {
r = ecalloc(n, sizeof(*r)); r = ecalloc(n, sizeof(*r));
@ -60,9 +64,9 @@ taketail(FILE *fp, const char *str, size_t n)
eprintf("%s: read error:", str); eprintf("%s: read error:", str);
do { do {
if (seenln && ring && ring[j]) { if (seenln && ring && ring[j].data) {
fputs(ring[j], stdout); fwrite(ring[j].data, 1, ring[j].len, stdout);
free(ring[j]); free(ring[j].data);
} else if (r) { } else if (r) {
efputrune(&r[j], stdout, "<stdout>"); efputrune(&r[j], stdout, "<stdout>");
} }
@ -97,7 +101,8 @@ main(int argc, char *argv[])
case 'n': case 'n':
mode = ARGC(); mode = ARGC();
numstr = EARGF(usage()); 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, '+')) if (strchr(numstr, '+'))
tail = dropinit; tail = dropinit;
break; break;