From 0e4faead440021d608c9321a8cae2e3cd8392639 Mon Sep 17 00:00:00 2001 From: emma Date: Tue, 29 Aug 2023 13:17:35 -0600 Subject: [PATCH] tail(1p): segfaults for some reason lol --- src/tail.c | 89 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/src/tail.c b/src/tail.c index d27829f..61b9f89 100644 --- a/src/tail.c +++ b/src/tail.c @@ -22,26 +22,78 @@ #include #include #include +#include #include #include "yac.h" -void tail(FILE *file, bool c, bool f, long num) { - long offset; - if (c) { fseek(file, offset, SEEK_END); } - else { - for +void tailc(FILE *file, long num) { + int byte; + char buf[num]; + long offset = -num; + + fseek(file, offset, SEEK_END); + for (int i = 0; (byte = fgetc(file)) != EOF; i++) { + buf[i] = byte; } + fputs(buf, stdout); +} + +void tailf(FILE *file) { + int byte; + + while(true) { + if ((byte = fgetc(file)) != EOF) { putchar(byte); } + } +} + +void tailn(FILE *file, long num) { + char *buf = calloc(4096, 1); + char *lines[num]; + int byte; + int lc = 0; + + for (int bc = 0; (byte = fgetc(file)) != EOF; bc++) { + if (bc == sizeof(buf)) { + int err; + if (err = realloc(buf, sizeof(buf) * 2) == NULL) { + // TODO: error handling + } + } + + buf[bc] = byte; + + if (byte == '\n') { + lines[lc] = buf; + bc = 0; + lc++; + } + + if (lc == num) { + for (int i = 0; i < lc; i++) { + lines[i] = lines[i + 1]; + } + lc--; + } + } + + int i; + if ((i = lc - num) < 0) { i = 0; } + + for (; i < lc; i++) { + fputs(lines[i], stdout); + } } int main(int argc, char *argv[]) { bool c = false; bool f = false; bool n = false; - long num; - int opt; int i; + int opt; + long num; + void (*fn)(FILE *, long) = tailn; extern int optind; while ((opt = getopt(argc, argv, "c:fn:")) != -1) { @@ -87,6 +139,7 @@ int main(int argc, char *argv[]) { */ case 'c': c = true; + fn = tailc; num = (long)optarg; break; case 'f': @@ -116,19 +169,21 @@ int main(int argc, char *argv[]) { return EX_USAGE; } - if (optind = argc) { - tail(stdin, c, f, num); - } - FILE *file; - for (i = optind; i < argc; i++) { - file = rfile(argv0, argv[i]); - if file != NULL { - tail(file, c, f, num); - if (file != stdin) { fclose(file); } + if (optind = argc) { + fn(stdin, num); + + if (f) { tailf(stdin); } + } else { + for (i = optind; i < argc; i++) { + if ((file = rpath(argv[0], argv[i])) != NULL) { + fn(file, num); + fclose(file); + } + + if (f) { tailf(file); } } } - return EX_OK; }