diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2015-11-19 17:50:05 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2015-11-19 17:50:05 +0000 |
commit | 7e93d06b71185308b6a3c3295b4bbead7f4d5aa0 (patch) | |
tree | 46befb3934164ee48f168e2cc84126558d3d225f /usr.bin/tail | |
parent | 3ea70f02c2b97325aeb062585273131d1d14106d (diff) |
another try to allow tailing multiple files. maybe it works?
commit now to allow people to test.
from Martijn van Duren
Diffstat (limited to 'usr.bin/tail')
-rw-r--r-- | usr.bin/tail/extern.h | 20 | ||||
-rw-r--r-- | usr.bin/tail/forward.c | 376 | ||||
-rw-r--r-- | usr.bin/tail/misc.c | 12 | ||||
-rw-r--r-- | usr.bin/tail/read.c | 18 | ||||
-rw-r--r-- | usr.bin/tail/reverse.c | 68 | ||||
-rw-r--r-- | usr.bin/tail/tail.c | 56 |
6 files changed, 322 insertions, 228 deletions
diff --git a/usr.bin/tail/extern.h b/usr.bin/tail/extern.h index 948f4e49bb0..628d875b1cb 100644 --- a/usr.bin/tail/extern.h +++ b/usr.bin/tail/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.11 2008/11/13 18:33:03 landry Exp $ */ +/* $OpenBSD: extern.h,v 1.12 2015/11/19 17:50:04 tedu Exp $ */ /* $NetBSD: extern.h,v 1.3 1994/11/23 07:42:00 jtc Exp $ */ /*- @@ -36,17 +36,23 @@ if (write(STDOUT_FILENO, p, size) != size) \ oerr(); +struct tailfile { + char *fname; + FILE *fp; + struct stat sb; +}; + enum STYLE { NOTSET = 0, FBYTES, FLINES, RBYTES, RLINES, REVERSE }; -void forward(FILE *, enum STYLE, off_t, struct stat *); -void reverse(FILE *, enum STYLE, off_t, struct stat *); +void forward(struct tailfile *, int, enum STYLE, off_t); +void reverse(struct tailfile *, int, enum STYLE, off_t); -int bytes(FILE *, off_t); -int lines(FILE *, off_t); +int bytes(struct tailfile *, off_t); +int lines(struct tailfile *, off_t); -void ierr(void); +void ierr(const char *); void oerr(void); +void printfname(const char *); extern int fflag, rflag, rval; -extern char *fname; extern int is_stdin; diff --git a/usr.bin/tail/forward.c b/usr.bin/tail/forward.c index a601f3ef063..a009ab698cc 100644 --- a/usr.bin/tail/forward.c +++ b/usr.bin/tail/forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: forward.c,v 1.26 2009/10/27 23:59:44 deraadt Exp $ */ +/* $OpenBSD: forward.c,v 1.27 2015/11/19 17:50:04 tedu Exp $ */ /* $NetBSD: forward.c,v 1.7 1996/02/13 16:49:10 ghudson Exp $ */ /*- @@ -38,13 +38,19 @@ #include <sys/event.h> #include <err.h> +#include <errno.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include "extern.h" -static int rlines(FILE *, off_t, struct stat *); +static int rlines(struct tailfile *, off_t); +static int tfqueue(struct tailfile *tf); +static const struct timespec *tfreopen(struct tailfile *tf); + +static int kq = -1; /* * forward -- display the file, from an offset, forward. @@ -69,179 +75,176 @@ static int rlines(FILE *, off_t, struct stat *); * NOREG cyclically read lines into a wrap-around array of buffers */ void -forward(FILE *fp, enum STYLE style, off_t off, struct stat *sbp) +forward(struct tailfile *tf, int nfiles, enum STYLE style, off_t off) { int ch; - struct stat nsb; - int kq, queue; + struct tailfile *ctf, *ltf; struct kevent ke; + const struct timespec *ts = NULL; + int i; + int nevents; - switch(style) { - case FBYTES: - if (off == 0) - break; - if (S_ISREG(sbp->st_mode)) { - if (sbp->st_size < off) - off = sbp->st_size; - if (fseeko(fp, off, SEEK_SET) == -1) { - ierr(); - return; - } - } else while (off--) - if ((ch = getc(fp)) == EOF) { - if (ferror(fp)) { - ierr(); + if (nfiles < 1) + return; + + if ((kq = kqueue()) < 0) + warn("kqueue"); + + for (i = 0; i < nfiles; i++) { + if (nfiles > 1) + printfname(tf[i].fname); + + switch(style) { + case FBYTES: + if (off == 0) + break; + if (S_ISREG(tf[i].sb.st_mode)) { + if (tf[i].sb.st_size < off) + off = tf[i].sb.st_size; + if (fseeko(tf[i].fp, off, SEEK_SET) == -1) { + ierr(tf[i].fname); return; } + } else while (off--) + if ((ch = getc(tf[i].fp)) == EOF) { + if (ferror(tf[i].fp)) { + ierr(tf[i].fname); + return; + } + break; + } + break; + case FLINES: + if (off == 0) break; + for (;;) { + if ((ch = getc(tf[i].fp)) == EOF) { + if (ferror(tf[i].fp)) { + ierr(tf[i].fname); + return; + } + break; + } + if (ch == '\n' && !--off) + break; } - break; - case FLINES: - if (off == 0) break; - for (;;) { - if ((ch = getc(fp)) == EOF) { - if (ferror(fp)) { - ierr(); + case RBYTES: + if (S_ISREG(tf[i].sb.st_mode)) { + if (tf[i].sb.st_size >= off && + fseeko(tf[i].fp, -off, SEEK_END) == -1) { + ierr(tf[i].fname); return; } - break; - } - if (ch == '\n' && !--off) - break; - } - break; - case RBYTES: - if (S_ISREG(sbp->st_mode)) { - if (sbp->st_size >= off && - fseeko(fp, -off, SEEK_END) == -1) { - ierr(); - return; - } - } else if (off == 0) { - while (getc(fp) != EOF) - ; - if (ferror(fp)) { - ierr(); - return; + } else if (off == 0) { + while (getc(tf[i].fp) != EOF) + ; + if (ferror(tf[i].fp)) { + ierr(tf[i].fname); + return; + } + } else { + if (bytes(&(tf[i]), off)) + return; } - } else { - if (bytes(fp, off)) - return; - } - break; - case RLINES: - if (S_ISREG(sbp->st_mode)) { - if (!off) { - if (fseeko(fp, (off_t)0, SEEK_END) == -1) { - ierr(); + break; + case RLINES: + if (S_ISREG(tf[i].sb.st_mode)) { + if (!off) { + if (fseeko(tf[i].fp, (off_t)0, + SEEK_END) == -1) { + ierr(tf[i].fname); + return; + } + } else if (rlines(&(tf[i]), off) != 0) + lines(&(tf[i]), off); + } else if (off == 0) { + while (getc(tf[i].fp) != EOF) + ; + if (ferror(tf[i].fp)) { + ierr(tf[i].fname); return; } - } else if (rlines(fp, off, sbp) != 0) - lines(fp, off); - } else if (off == 0) { - while (getc(fp) != EOF) - ; - if (ferror(fp)) { - ierr(); - return; + } else { + if (lines(&(tf[i]), off)) + return; } - } else { - if (lines(fp, off)) - return; + break; + default: + err(1, "Unsupported style"); } - break; - } - kq = -1; -kq_retry: - if (fflag && ((kq = kqueue()) >= 0)) { - EV_SET(&ke, fileno(fp), EVFILT_READ, - EV_ENABLE | EV_ADD | EV_CLEAR, - 0, - 0, NULL); - if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) { - close(kq); - kq = -1; - } else if (S_ISREG(sbp->st_mode)) { - EV_SET(&ke, fileno(fp), EVFILT_VNODE, - EV_ENABLE | EV_ADD | EV_CLEAR, - NOTE_DELETE | NOTE_RENAME | NOTE_TRUNCATE, - 0, NULL); - if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) { - close(kq); - kq = -1; - } - } + if (tfqueue(&(tf[i])) == -1) + warn("Unable to follow %s", tf[i].fname); + } + ltf = &(tf[i-1]); + + (void)fflush(stdout); + if (!fflag || kq < 0) + return; - for (;;) { - while (!feof(fp) && (ch = getc(fp)) != EOF) - if (putchar(ch) == EOF) - oerr(); - if (ferror(fp)) { - ierr(); - if (kq != -1) + while (1) { + if ((nevents = kevent(kq, NULL, 0, &ke, 1, ts)) <= 0) { + if (errno == EINTR) { close(kq); - return; - } - (void)fflush(stdout); - if (!fflag) - break; - clearerr(fp); - queue = 1; - if (kq < 0 || kevent(kq, NULL, 0, &ke, 1, NULL) <= 0) { - queue = 0; - sleep(1); - } else if (ke.filter == EVFILT_READ) { - continue; - } else if ((ke.fflags & NOTE_TRUNCATE) == 0) { - /* - * File was renamed or deleted. - * - * Continue to look at it until a new file reappears - * with the same name. - * Fall back to the old algorithm for that. - */ - close(kq); - kq = -1; + return; + } } - if (is_stdin || stat(fname, &nsb) != 0) - continue; - /* Reopen file if the inode changes or file was truncated */ - if (nsb.st_ino != sbp->st_ino) { - warnx("%s has been replaced, reopening.", fname); - if ((fp = freopen(fname, "r", fp)) == NULL) { - ierr(); - if (kq >= 0) - close(kq); - return; + ctf = ke.udata; + if (nevents > 0) { + if (ke.filter == EVFILT_READ) { + if (ctf != ltf) { + printfname(ctf->fname); + ltf = ctf; + } + clearerr(ctf->fp); + while (!feof(ctf->fp) && + (ch = getc(ctf->fp)) != EOF) { + if (putchar(ch) == EOF) + oerr(); + } + if (ferror(ctf->fp)) { + ierr(ctf->fname); + fclose(ctf->fp); + warn("Lost file %s", ctf->fname); + continue; + } + (void)fflush(stdout); + clearerr(ctf->fp); + } else if (ke.filter == EVFILT_VNODE) { + if (ke.fflags & (NOTE_DELETE | NOTE_RENAME)) { + /* + * File was deleted or renamed. + * + * Continue to look at it until + * a new file reappears with + * the same name. + */ + (void) tfreopen(ctf); + } else if (ke.fflags & NOTE_TRUNCATE) { + warnx("%s has been truncated, " + "resetting.", ctf->fname); + fpurge(ctf->fp); + rewind(ctf->fp); + } } - (void)memcpy(sbp, &nsb, sizeof(nsb)); - goto kq_retry; - } else if ((queue && (ke.fflags & NOTE_TRUNCATE)) || - (!queue && nsb.st_size < sbp->st_size)) { - warnx("%s has been truncated, resetting.", fname); - fpurge(fp); - rewind(fp); } - (void)memcpy(sbp, &nsb, sizeof(nsb)); + ts = tfreopen(NULL); } - if (kq >= 0) - close(kq); } /* * rlines -- display the last offset lines of the file. */ static int -rlines(FILE *fp, off_t off, struct stat *sbp) +rlines(struct tailfile *tf, off_t off) { off_t pos; int ch; - pos = sbp->st_size; + pos = tf->sb.st_size; if (pos == 0) return (0); @@ -253,33 +256,106 @@ rlines(FILE *fp, off_t off, struct stat *sbp) ch = EOF; for (; off > 0 && pos >= 0; pos--) { /* A seek per char isn't a problem with a smart stdio */ - if (fseeko(fp, pos, SEEK_SET) == -1) { - ierr(); + if (fseeko(tf[0].fp, pos, SEEK_SET) == -1) { + ierr(tf->fname); return (1); } - if ((ch = getc(fp)) == '\n') + if ((ch = getc(tf[0].fp)) == '\n') off--; else if (ch == EOF) { - if (ferror(fp)) { - ierr(); + if (ferror(tf[0].fp)) { + ierr(tf->fname); return (1); } break; } } /* If we read until start of file, put back last read char */ - if (pos < 0 && off > 0 && ch != EOF && ungetc(ch, fp) == EOF) { - ierr(); + if (pos < 0 && off > 0 && ch != EOF && ungetc(ch, tf[0].fp) == EOF) { + ierr(tf->fname); return (1); } - while (!feof(fp) && (ch = getc(fp)) != EOF) + while (!feof(tf[0].fp) && (ch = getc(tf[0].fp)) != EOF) if (putchar(ch) == EOF) oerr(); - if (ferror(fp)) { - ierr(); + if (ferror(tf[0].fp)) { + ierr(tf->fname); return (1); } return (0); } + +static int +tfqueue(struct tailfile *tf) +{ + struct kevent ke[2]; + int i = 1; + + if (kq < 0) { + errno = EBADF; + return -1; + } + + EV_SET(&(ke[0]), fileno(tf->fp), EVFILT_READ, + EV_ENABLE | EV_ADD | EV_CLEAR, 0, 0, tf); + + if (S_ISREG(tf->sb.st_mode)) { + i = 2; + EV_SET(&(ke[1]), fileno(tf->fp), EVFILT_VNODE, + EV_ENABLE | EV_ADD | EV_CLEAR, + NOTE_DELETE | NOTE_RENAME | NOTE_TRUNCATE, + 0, tf); + } + if (kevent(kq, ke, i, NULL, 0, NULL) < 0) { + ierr(tf->fname); + return -1; + } + return 0; +} + +#define AFILESINCR 8 +static const struct timespec * +tfreopen(struct tailfile *tf) { + static struct tailfile **reopen = NULL; + static int nfiles = 0, afiles = 0; + static const struct timespec ts = {1, 0}; + + struct stat sb; + struct tailfile **treopen, *ttf; + int i; + + if (tf && ((stat(tf->fname, &sb) != 0) || sb.st_ino != tf->sb.st_ino)) { + if (afiles < ++nfiles) { + afiles += AFILESINCR; + treopen = reallocarray(reopen, afiles, sizeof(*reopen)); + if (treopen) + reopen = treopen; + else + afiles -= AFILESINCR; + } + if (nfiles < afiles) + reopen[nfiles-1] = tf; + } + + for (i = 0; i < nfiles; i++) { + ttf = reopen[i]; + if (stat(ttf->fname, &sb) == -1) + continue; + if (sb.st_ino != ttf->sb.st_ino) { + (void) memcpy(&(ttf->sb), &sb, sizeof(ttf->sb)); + ttf->fp = freopen(ttf->fname, "r", ttf->fp); + if (ttf->fp == NULL) + ierr(ttf->fname); + else { + warnx("%s has been replaced, reopening.", + ttf->fname); + tfqueue(ttf); + } + } + reopen[i] = reopen[--nfiles]; + } + + return nfiles ? &ts : NULL; +} diff --git a/usr.bin/tail/misc.c b/usr.bin/tail/misc.c index 97650b4f85b..80187d406d6 100644 --- a/usr.bin/tail/misc.c +++ b/usr.bin/tail/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.8 2009/10/27 23:59:44 deraadt Exp $ */ +/* $OpenBSD: misc.c,v 1.9 2015/11/19 17:50:04 tedu Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -41,7 +41,7 @@ #include "extern.h" void -ierr(void) +ierr(const char *fname) { warn("%s", fname); rval = 1; @@ -52,3 +52,11 @@ oerr(void) { err(1, "stdout"); } + +void printfname(const char *fname) +{ + static int first = 1; + (void)printf("%s==> %s <==\n", first ? "" : "\n", fname); + first = 0; + (void)fflush(stdout); +} diff --git a/usr.bin/tail/read.c b/usr.bin/tail/read.c index 757e8cd12b0..72d521d037c 100644 --- a/usr.bin/tail/read.c +++ b/usr.bin/tail/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.16 2015/03/26 21:26:43 tobias Exp $ */ +/* $OpenBSD: read.c,v 1.17 2015/11/19 17:50:04 tedu Exp $ */ /* $NetBSD: read.c,v 1.4 1994/11/23 07:42:07 jtc Exp $ */ /*- @@ -59,7 +59,7 @@ * */ int -bytes(FILE *fp, off_t off) +bytes(struct tailfile *tf, off_t off) { int ch; size_t len, tlen; @@ -73,15 +73,15 @@ bytes(FILE *fp, off_t off) if ((sp = p = malloc(off)) == NULL) err(1, NULL); - for (wrap = 0, ep = p + off; (ch = getc(fp)) != EOF;) { + for (wrap = 0, ep = p + off; (ch = getc(tf->fp)) != EOF;) { *p = ch; if (++p == ep) { wrap = 1; p = sp; } } - if (ferror(fp)) { - ierr(); + if (ferror(tf->fp)) { + ierr(tf->fname); free(sp); return(1); } @@ -135,7 +135,7 @@ bytes(FILE *fp, off_t off) * */ int -lines(FILE *fp, off_t off) +lines(struct tailfile *tf, off_t off) { struct { size_t blen; @@ -156,7 +156,7 @@ lines(FILE *fp, off_t off) blen = cnt = recno = wrap = 0; - while ((ch = getc(fp)) != EOF) { + while ((ch = getc(tf->fp)) != EOF) { if (++cnt > blen) { newsize = blen + 1024; if ((newp = realloc(sp, newsize)) == NULL) @@ -184,8 +184,8 @@ lines(FILE *fp, off_t off) } } } - if (ferror(fp)) { - ierr(); + if (ferror(tf->fp)) { + ierr(tf->fname); rc = 1; goto done; } diff --git a/usr.bin/tail/reverse.c b/usr.bin/tail/reverse.c index a88041078a6..144c481b6f0 100644 --- a/usr.bin/tail/reverse.c +++ b/usr.bin/tail/reverse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: reverse.c,v 1.20 2015/07/22 16:37:04 tobias Exp $ */ +/* $OpenBSD: reverse.c,v 1.21 2015/11/19 17:50:04 tedu Exp $ */ /* $NetBSD: reverse.c,v 1.6 1994/11/23 07:42:10 jtc Exp $ */ /*- @@ -43,12 +43,12 @@ #include "extern.h" static void r_buf(FILE *); -static int r_reg(FILE *, enum STYLE, off_t, struct stat *); +static int r_reg(struct tailfile *, enum STYLE, off_t); -#define COPYCHAR(fp, ch) \ +#define COPYCHAR(tf, ch) \ do { \ - if ((ch = getc(fp)) == EOF) { \ - ierr(); \ + if ((ch = getc(tf->fp)) == EOF) { \ + ierr(tf->fname); \ return (0); \ } \ if (putchar(ch) == EOF) { \ @@ -76,37 +76,47 @@ static int r_reg(FILE *, enum STYLE, off_t, struct stat *); * NOREG cyclically read input into a linked list of buffers */ void -reverse(FILE *fp, enum STYLE style, off_t off, struct stat *sbp) +reverse(struct tailfile *tf, int nfiles, enum STYLE style, off_t off) { + int i; + if (style != REVERSE && off == 0) return; - if (!S_ISREG(sbp->st_mode) || r_reg(fp, style, off, sbp) != 0) - switch(style) { - case FBYTES: - case RBYTES: - (void)bytes(fp, off); - break; - case FLINES: - case RLINES: - (void)lines(fp, off); - break; - case REVERSE: - r_buf(fp); - break; + for (i = 0; i < nfiles; i++) { + if (nfiles > 1) + printfname(tf[i].fname); + if (!S_ISREG(tf[i].sb.st_mode) || + r_reg(&(tf[i]), style, off) != 0) { + switch(style) { + case FBYTES: + case RBYTES: + (void)bytes(&(tf[i]), off); + break; + case FLINES: + case RLINES: + (void)lines(&(tf[i]), off); + break; + case REVERSE: + r_buf(tf[i].fp); + break; + default: + err(1, "Unsupported style"); + } } + } } /* * r_reg -- display a regular file in reverse order by line. */ static int -r_reg(FILE *fp, enum STYLE style, off_t off, struct stat *sbp) +r_reg(struct tailfile *tf, enum STYLE style, off_t off) { off_t start, pos, end; int ch; - end = sbp->st_size; + end = tf->sb.st_size; if (end == 0) return (0); @@ -120,29 +130,29 @@ r_reg(FILE *fp, enum STYLE style, off_t off, struct stat *sbp) for (; pos >= start; pos--) { /* A seek per char isn't a problem with a smart stdio */ - if (fseeko(fp, pos, SEEK_SET) != 0) { - ierr(); + if (fseeko(tf->fp, pos, SEEK_SET) != 0) { + ierr(tf->fname); return (0); } - if ((ch = getc(fp)) == '\n') { + if ((ch = getc(tf->fp)) == '\n') { while (--end > pos) - COPYCHAR(fp, ch); + COPYCHAR(tf, ch); end++; if (style == RLINES && --off == 0) break; } else if (ch == EOF) { - ierr(); + ierr(tf->fname); return (0); } } if (pos < start) { - if (ch != EOF && ungetc(ch, fp) == EOF) { - ierr(); + if (ch != EOF && ungetc(ch, tf->fp) == EOF) { + ierr(tf->fname); return (0); } while (--end >= start) - COPYCHAR(fp, ch); + COPYCHAR(tf, ch); } return (0); } diff --git a/usr.bin/tail/tail.c b/usr.bin/tail/tail.c index e543e0b9b2f..0d66b83e54f 100644 --- a/usr.bin/tail/tail.c +++ b/usr.bin/tail/tail.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tail.c,v 1.19 2015/10/09 01:37:09 deraadt Exp $ */ +/* $OpenBSD: tail.c,v 1.20 2015/11/19 17:50:04 tedu Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -45,7 +45,6 @@ #include "extern.h" int fflag, rflag, rval; -char *fname; int is_stdin; static void obsolete(char **); @@ -54,11 +53,11 @@ static void usage(void); int main(int argc, char *argv[]) { - struct stat sb; - FILE *fp; + struct tailfile *tf; off_t off = 0; enum STYLE style; - int ch, first; + int ch; + int i; char *p; if (pledge("stdio rpath", NULL) == -1) @@ -123,9 +122,6 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (fflag && argc > 1) - errx(1, "-f option only appropriate for a single file"); - /* * If displaying in reverse, don't permit follow option, and convert * style values. @@ -153,35 +149,33 @@ main(int argc, char *argv[]) } } - if (*argv) - for (first = 1; (fname = *argv++);) { - if ((fp = fopen(fname, "r")) == NULL || - fstat(fileno(fp), &sb)) { - ierr(); + if ((tf = reallocarray(NULL, argc ? argc : 1, sizeof(*tf))) == NULL) + err(1, "reallocarray"); + + if (argc) { + for (i = 0; (tf[i].fname = *argv++); i++) { + if ((tf[i].fp = fopen(tf[i].fname, "r")) == NULL || + fstat(fileno(tf[i].fp), &(tf[i].sb))) { + ierr(tf[i].fname); + i--; continue; } - if (argc > 1) { - (void)printf("%s==> %s <==\n", - first ? "" : "\n", fname); - first = 0; - (void)fflush(stdout); - } - - if (rflag) - reverse(fp, style, off, &sb); - else - forward(fp, style, off, &sb); - (void)fclose(fp); } + if (rflag) + reverse(tf, i, style, off); + else + forward(tf, i, style, off); + } else { if (pledge("stdio", NULL) == -1) err(1, "pledge"); - fname = "stdin"; + tf[0].fname = "stdin"; + tf[0].fp = stdin; is_stdin = 1; - if (fstat(fileno(stdin), &sb)) { - ierr(); + if (fstat(fileno(stdin), &(tf[0].sb))) { + ierr(tf[0].fname); exit(1); } @@ -189,16 +183,16 @@ main(int argc, char *argv[]) * Determine if input is a pipe. 4.4BSD will set the SOCKET * bit in the st_mode field for pipes. Fix this then. */ - if (lseek(fileno(stdin), (off_t)0, SEEK_CUR) == -1 && + if (lseek(fileno(tf[0].fp), (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) { errno = 0; fflag = 0; /* POSIX.2 requires this. */ } if (rflag) - reverse(stdin, style, off, &sb); + reverse(tf, 1, style, off); else - forward(stdin, style, off, &sb); + forward(tf, 1, style, off); } exit(rval); } |