diff --git a/tail.c b/tail.c index a678a93..3ea4739 100644 --- a/tail.c +++ b/tail.c @@ -8,58 +8,7 @@ #include "text.h" #include "util.h" -static void dropinit(FILE *, const char *, long); -static void taketail(FILE *, const char *, long); - -static void -usage(void) -{ - eprintf("usage: %s [-n lines] [file]\n", argv0); -} - -int -main(int argc, char *argv[]) -{ - long n = 10; - FILE *fp; - void (*tail)(FILE *, const char *, long) = taketail; - char *lines; - int ret = 0; - int newline, many; - - ARGBEGIN { - case 'n': - lines = EARGF(usage()); - n = estrtonum(lines, 0, LONG_MAX); - if (lines[0] == '+') - tail = dropinit; - break; - ARGNUM: - n = ARGNUMF(); - break; - default: - usage(); - } ARGEND; - if (argc == 0) { - tail(stdin, "", n); - } else { - many = argc > 1; - for (newline = 0; argc > 0; argc--, argv++) { - if (!(fp = fopen(argv[0], "r"))) { - weprintf("fopen %s:", argv[0]); - ret = 1; - continue; - } - if (many) - printf("%s==> %s <==\n", - newline ? "\n" : "", argv[0]); - newline = 1; - tail(fp, argv[0], n); - fclose(fp); - } - } - return ret; -} +static int fflag = 0; static void dropinit(FILE *fp, const char *str, long n) @@ -69,8 +18,8 @@ dropinit(FILE *fp, const char *str, long n) ssize_t len; unsigned long i = 0; - while (i < n && ((len = getline(&buf, &size, fp)) != -1)) - if (len && buf[len - 1] == '\n') + while (i < n && (len = getline(&buf, &size, fp)) != -1) + if (len > 0 && buf[len - 1] == '\n') i++; free(buf); concat(fp, str, stdout, ""); @@ -96,7 +45,77 @@ taketail(FILE *fp, const char *str, long n) fputs(ring[j], stdout); free(ring[j]); } - } while ((j = (j+1)%n) != i); + } while ((j = (j + 1) % n) != i); + free(ring); free(size); } + +static void +usage(void) +{ + eprintf("usage: %s [-f] [-n lines] [file ...]\n", argv0); +} + +int +main(int argc, char *argv[]) +{ + FILE *fp; + size_t n = 10, tmpsize; + int ret = 0, newline, many; + char *lines, *tmp; + void (*tail)(FILE *, const char *, long) = taketail; + + ARGBEGIN { + case 'f': + fflag = 1; + break; + case 'n': + lines = EARGF(usage()); + n = estrtonum(lines, 0, LONG_MAX); + if (lines[0] == '+') + tail = dropinit; + break; + ARGNUM: + n = ARGNUMF(); + break; + default: + usage(); + } ARGEND; + + if (argc == 0) + tail(stdin, "", n); + else { + if ((many = argc > 1) && fflag) + usage(); + for (newline = 0; argc > 0; argc--, argv++) { + if (!(fp = fopen(argv[0], "r"))) { + weprintf("fopen %s:", argv[0]); + ret = 1; + continue; + } + if (many) + printf("%s==> %s <==\n", + newline ? "\n" : "", argv[0]); + newline = 1; + tail(fp, argv[0], n); + + if (fflag && argc == 1) { + for(;; tmp = NULL, tmpsize = 0) { + while (getline(&tmp, &tmpsize, fp) != -1) { + fputs(tmp, stdout); + fflush(stdout); + free(tmp); + tmp = NULL; + tmpsize = 0; + } + if (ferror(fp)) + eprintf("readline '%s':", argv[0]); + clearerr(fp); + } + } + fclose(fp); + } + } + return ret; +}