sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

commit 2a83c2c8bef7f0e48d575e14d49aa22e44b649dd
parent 6b63fc2f2bcf55d61ab81a4ae6282e563b6b07aa
Author: FRIGN <dev@frign.de>
Date:   Mon,  9 Feb 2015 15:06:17 +0100

Add f-flag to tail(1) and refactor code

Diffstat:
Mtail.c | 119++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 69 insertions(+), 50 deletions(-)

diff --git a/tail.c b/tail.c @@ -8,26 +8,68 @@ #include "text.h" #include "util.h" -static void dropinit(FILE *, const char *, long); -static void taketail(FILE *, const char *, long); +static int fflag = 0; + +static void +dropinit(FILE *fp, const char *str, long n) +{ + char *buf = NULL; + size_t size = 0; + ssize_t len; + unsigned long i = 0; + + while (i < n && (len = getline(&buf, &size, fp)) != -1) + if (len > 0 && buf[len - 1] == '\n') + i++; + free(buf); + concat(fp, str, stdout, "<stdout>"); +} + +static void +taketail(FILE *fp, const char *str, long n) +{ + char **ring = NULL; + long i, j; + size_t *size = NULL; + + ring = ecalloc(n, sizeof *ring); + size = ecalloc(n, sizeof *size); + + for (i = j = 0; getline(&ring[i], &size[i], fp) != -1; i = j = (i + 1) % n) + ; + if (ferror(fp)) + eprintf("%s: read error:", str); + + do { + if (ring[j]) { + fputs(ring[j], stdout); + free(ring[j]); + } + } while ((j = (j + 1) % n) != i); + + free(ring); + free(size); +} static void usage(void) { - eprintf("usage: %s [-n lines] [file]\n", argv0); + eprintf("usage: %s [-f] [-n lines] [file ...]\n", argv0); } int main(int argc, char *argv[]) { - long n = 10; FILE *fp; + size_t n = 10, tmpsize; + int ret = 0, newline, many; + char *lines, *tmp; void (*tail)(FILE *, const char *, long) = taketail; - char *lines; - int ret = 0; - int newline, many; ARGBEGIN { + case 'f': + fflag = 1; + break; case 'n': lines = EARGF(usage()); n = estrtonum(lines, 0, LONG_MAX); @@ -40,10 +82,12 @@ main(int argc, char *argv[]) default: usage(); } ARGEND; - if (argc == 0) { + + if (argc == 0) tail(stdin, "<stdin>", n); - } else { - many = argc > 1; + 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]); @@ -55,48 +99,23 @@ main(int argc, char *argv[]) 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; } - -static void -dropinit(FILE *fp, const char *str, long n) -{ - char *buf = NULL; - size_t size = 0; - ssize_t len; - unsigned long i = 0; - - while (i < n && ((len = getline(&buf, &size, fp)) != -1)) - if (len && buf[len - 1] == '\n') - i++; - free(buf); - concat(fp, str, stdout, "<stdout>"); -} - -static void -taketail(FILE *fp, const char *str, long n) -{ - char **ring = NULL; - long i, j; - size_t *size = NULL; - - ring = ecalloc(n, sizeof *ring); - size = ecalloc(n, sizeof *size); - - for (i = j = 0; getline(&ring[i], &size[i], fp) != -1; i = j = (i + 1) % n) - ; - if (ferror(fp)) - eprintf("%s: read error:", str); - - do { - if (ring[j]) { - fputs(ring[j], stdout); - free(ring[j]); - } - } while ((j = (j+1)%n) != i); - free(ring); - free(size); -}