Date: Fri, 26 Jun 2009 01:08:35 +0000 (UTC) From: Brian Somers <brian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r195027 - stable/7/usr.bin/tail Message-ID: <200906260108.n5Q18ZBs070148@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: brian Date: Fri Jun 26 01:08:35 2009 New Revision: 195027 URL: http://svn.freebsd.org/changeset/base/195027 Log: MFC: r193488: Persist forever when tailing with -F and ignore ENOENT failures. Correct the filename in other error messages. Modified: stable/7/usr.bin/tail/ (props changed) stable/7/usr.bin/tail/extern.h stable/7/usr.bin/tail/forward.c stable/7/usr.bin/tail/misc.c stable/7/usr.bin/tail/read.c stable/7/usr.bin/tail/reverse.c stable/7/usr.bin/tail/tail.1 stable/7/usr.bin/tail/tail.c Modified: stable/7/usr.bin/tail/extern.h ============================================================================== --- stable/7/usr.bin/tail/extern.h Fri Jun 26 01:04:50 2009 (r195026) +++ stable/7/usr.bin/tail/extern.h Fri Jun 26 01:08:35 2009 (r195027) @@ -61,16 +61,15 @@ typedef struct file_info file_info_t; enum STYLE { NOTSET = 0, FBYTES, FLINES, RBYTES, RLINES, REVERSE }; void follow(file_info_t *, enum STYLE, off_t); -void forward(FILE *, enum STYLE, off_t, struct stat *); -void reverse(FILE *, enum STYLE, off_t, struct stat *); +void forward(FILE *, const char *, enum STYLE, off_t, struct stat *); +void reverse(FILE *, const char *, enum STYLE, off_t, struct stat *); -int bytes(FILE *, off_t); -int lines(FILE *, off_t); +int bytes(FILE *, const char *, off_t); +int lines(FILE *, const char *, off_t); -void ierr(void); +void ierr(const char *); void oerr(void); int mapprint(struct mapinfo *, off_t, off_t); int maparound(struct mapinfo *, off_t); extern int Fflag, fflag, qflag, rflag, rval, no_files; -extern const char *fname; Modified: stable/7/usr.bin/tail/forward.c ============================================================================== --- stable/7/usr.bin/tail/forward.c Fri Jun 26 01:04:50 2009 (r195026) +++ stable/7/usr.bin/tail/forward.c Fri Jun 26 01:08:35 2009 (r195027) @@ -61,8 +61,8 @@ static const char sccsid[] = "@(#)forwar #include "extern.h" -static void rlines(FILE *, off_t, struct stat *); -static void show(file_info_t *); +static void rlines(FILE *, const char *fn, off_t, struct stat *); +static int show(file_info_t *); static void set_events(file_info_t *files); /* defines for inner loop actions */ @@ -99,7 +99,7 @@ static const file_info_t *last; * 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(FILE *fp, const char *fn, enum STYLE style, off_t off, struct stat *sbp) { int ch; @@ -111,13 +111,13 @@ forward(FILE *fp, enum STYLE style, off_ if (sbp->st_size < off) off = sbp->st_size; if (fseeko(fp, off, SEEK_SET) == -1) { - ierr(); + ierr(fn); return; } } else while (off--) if ((ch = getc(fp)) == EOF) { if (ferror(fp)) { - ierr(); + ierr(fn); return; } break; @@ -129,7 +129,7 @@ forward(FILE *fp, enum STYLE style, off_ for (;;) { if ((ch = getc(fp)) == EOF) { if (ferror(fp)) { - ierr(); + ierr(fn); return; } break; @@ -142,36 +142,36 @@ forward(FILE *fp, enum STYLE style, off_ if (S_ISREG(sbp->st_mode)) { if (sbp->st_size >= off && fseeko(fp, -off, SEEK_END) == -1) { - ierr(); + ierr(fn); return; } } else if (off == 0) { while (getc(fp) != EOF); if (ferror(fp)) { - ierr(); + ierr(fn); return; } } else - if (bytes(fp, off)) + if (bytes(fp, fn, off)) return; break; case RLINES: if (S_ISREG(sbp->st_mode)) if (!off) { if (fseeko(fp, (off_t)0, SEEK_END) == -1) { - ierr(); + ierr(fn); return; } } else - rlines(fp, off, sbp); + rlines(fp, fn, off, sbp); else if (off == 0) { while (getc(fp) != EOF); if (ferror(fp)) { - ierr(); + ierr(fn); return; } } else - if (lines(fp, off)) + if (lines(fp, fn, off)) return; break; default: @@ -182,7 +182,7 @@ forward(FILE *fp, enum STYLE style, off_ if (putchar(ch) == EOF) oerr(); if (ferror(fp)) { - ierr(); + ierr(fn); return; } (void)fflush(stdout); @@ -192,10 +192,7 @@ forward(FILE *fp, enum STYLE style, off_ * rlines -- display the last offset lines of the file. */ static void -rlines(fp, off, sbp) - FILE *fp; - off_t off; - struct stat *sbp; +rlines(FILE *fp, const char *fn, off_t off, struct stat *sbp) { struct mapinfo map; off_t curoff, size; @@ -214,7 +211,7 @@ rlines(fp, off, sbp) curoff = size - 2; while (curoff >= 0) { if (curoff < map.mapoff && maparound(&map, curoff) != 0) { - ierr(); + ierr(fn); return; } for (i = curoff - map.mapoff; i >= 0; i--) @@ -227,41 +224,44 @@ rlines(fp, off, sbp) } curoff++; if (mapprint(&map, curoff, size - curoff) != 0) { - ierr(); + ierr(fn); exit(1); } /* Set the file pointer to reflect the length displayed. */ if (fseeko(fp, sbp->st_size, SEEK_SET) == -1) { - ierr(); + ierr(fn); return; } if (map.start != NULL && munmap(map.start, map.maplen)) { - ierr(); + ierr(fn); return; } } -static void +static int show(file_info_t *file) { - int ch; + int ch; - while ((ch = getc(file->fp)) != EOF) { - if (last != file && no_files > 1) { - if (!qflag) - (void)printf("\n==> %s <==\n", file->file_name); - last = file; - } - if (putchar(ch) == EOF) - oerr(); - } - (void)fflush(stdout); - if (ferror(file->fp)) { - file->fp = NULL; - ierr(); - } else - clearerr(file->fp); + while ((ch = getc(file->fp)) != EOF) { + if (last != file && no_files > 1) { + if (!qflag) + (void)printf("\n==> %s <==\n", file->file_name); + last = file; + } + if (putchar(ch) == EOF) + oerr(); + } + (void)fflush(stdout); + if (ferror(file->fp)) { + fclose(file->fp); + file->fp = NULL; + ierr(file->file_name); + return 0; + } + clearerr(file->fp); + return 1; } static void @@ -309,7 +309,7 @@ set_events(file_info_t *files) void follow(file_info_t *files, enum STYLE style, off_t off) { - int active, i, n = -1; + int active, ev_change, i, n = -1; struct stat sb2; file_info_t *file; struct timespec ts; @@ -325,12 +325,12 @@ follow(file_info_t *files, enum STYLE st n++; if (no_files > 1 && !qflag) (void)printf("\n==> %s <==\n", file->file_name); - forward(file->fp, style, off, &file->st); + forward(file->fp, file->file_name, style, off, &file->st); if (Fflag && fileno(file->fp) != STDIN_FILENO) - n++; + n++; } } - if (! active) + if (!Fflag && !active) return; last = --file; @@ -344,28 +344,56 @@ follow(file_info_t *files, enum STYLE st set_events(files); for (;;) { - for (i = 0, file = files; i < no_files; i++, file++) { - if (! file->fp) - continue; - if (Fflag && file->fp && fileno(file->fp) != STDIN_FILENO) { - if (stat(file->file_name, &sb2) == 0 && - (sb2.st_ino != file->st.st_ino || - sb2.st_dev != file->st.st_dev || - sb2.st_nlink == 0)) { - show(file); - file->fp = freopen(file->file_name, "r", file->fp); - if (file->fp == NULL) { - ierr(); - continue; - } else { - memcpy(&file->st, &sb2, sizeof(struct stat)); - set_events(files); + ev_change = 0; + if (Fflag) { + for (i = 0, file = files; i < no_files; i++, file++) { + if (!file->fp) { + file->fp = fopen(file->file_name, "r"); + if (file->fp != NULL && + fstat(fileno(file->fp), &file->st) + == -1) { + fclose(file->fp); + file->fp = NULL; } + if (file->fp != NULL) + ev_change++; + continue; + } + if (fileno(file->fp) == STDIN_FILENO) + continue; + if (stat(file->file_name, &sb2) == -1) { + if (errno != ENOENT) + ierr(file->file_name); + show(file); + fclose(file->fp); + file->fp = NULL; + ev_change++; + continue; + } + + if (sb2.st_ino != file->st.st_ino || + sb2.st_dev != file->st.st_dev || + sb2.st_nlink == 0) { + show(file); + file->fp = freopen(file->file_name, "r", + file->fp); + if (file->fp != NULL) + memcpy(&file->st, &sb2, + sizeof(struct stat)); + else if (errno != ENOENT) + ierr(file->file_name); + ev_change++; } } - show(file); } + for (i = 0, file = files; i < no_files; i++, file++) + if (file->fp && !show(file)) + ev_change++; + + if (ev_change) + set_events(files); + switch (action) { case USE_KQUEUE: ts.tv_sec = 1; @@ -381,9 +409,9 @@ follow(file_info_t *files, enum STYLE st /* timeout */ break; } else if (ev->filter == EVFILT_READ && ev->data < 0) { - /* file shrank, reposition to end */ + /* file shrank, reposition to end */ if (lseek(ev->ident, (off_t)0, SEEK_END) == -1) { - ierr(); + ierr(file->file_name); continue; } } Modified: stable/7/usr.bin/tail/misc.c ============================================================================== --- stable/7/usr.bin/tail/misc.c Fri Jun 26 01:04:50 2009 (r195026) +++ stable/7/usr.bin/tail/misc.c Fri Jun 26 01:08:35 2009 (r195027) @@ -56,7 +56,7 @@ static const char sccsid[] = "@(#)misc.c #include "extern.h" void -ierr() +ierr(const char *fname) { warn("%s", fname); rval = 1; Modified: stable/7/usr.bin/tail/read.c ============================================================================== --- stable/7/usr.bin/tail/read.c Fri Jun 26 01:04:50 2009 (r195026) +++ stable/7/usr.bin/tail/read.c Fri Jun 26 01:08:35 2009 (r195027) @@ -66,7 +66,7 @@ static const char sccsid[] = "@(#)read.c * the end. */ int -bytes(FILE *fp, off_t off) +bytes(FILE *fp, const char *fn, off_t off) { int ch, len, tlen; char *ep, *p, *t; @@ -84,7 +84,7 @@ bytes(FILE *fp, off_t off) } } if (ferror(fp)) { - ierr(); + ierr(fn); free(sp); return 1; } @@ -136,7 +136,7 @@ bytes(FILE *fp, off_t off) * the end. */ int -lines(FILE *fp, off_t off) +lines(FILE *fp, const char *fn, off_t off) { struct { int blen; @@ -178,7 +178,7 @@ lines(FILE *fp, off_t off) } } if (ferror(fp)) { - ierr(); + ierr(fn); rc = 1; goto done; } Modified: stable/7/usr.bin/tail/reverse.c ============================================================================== --- stable/7/usr.bin/tail/reverse.c Fri Jun 26 01:04:50 2009 (r195026) +++ stable/7/usr.bin/tail/reverse.c Fri Jun 26 01:08:35 2009 (r195027) @@ -58,8 +58,8 @@ __FBSDID("$FreeBSD$"); #include "extern.h" -static void r_buf(FILE *); -static void r_reg(FILE *, enum STYLE, off_t, struct stat *); +static void r_buf(FILE *, const char *); +static void r_reg(FILE *, const char *, enum STYLE, off_t, struct stat *); /* * reverse -- display input in reverse order by line. @@ -80,25 +80,25 @@ static void r_reg(FILE *, enum STYLE, of * NOREG cyclically read input into a linked list of buffers */ void -reverse(FILE *fp, enum STYLE style, off_t off, struct stat *sbp) +reverse(FILE *fp, const char *fn, enum STYLE style, off_t off, struct stat *sbp) { if (style != REVERSE && off == 0) return; if (S_ISREG(sbp->st_mode)) - r_reg(fp, style, off, sbp); + r_reg(fp, fn, style, off, sbp); else switch(style) { case FBYTES: case RBYTES: - bytes(fp, off); + bytes(fp, fn, off); break; case FLINES: case RLINES: - lines(fp, off); + lines(fp, fn, off); break; case REVERSE: - r_buf(fp); + r_buf(fp, fn); break; default: break; @@ -109,7 +109,7 @@ reverse(FILE *fp, enum STYLE style, off_ * r_reg -- display a regular file in reverse order by line. */ static void -r_reg(FILE *fp, enum STYLE style, off_t off, struct stat *sbp) +r_reg(FILE *fp, const char *fn, enum STYLE style, off_t off, struct stat *sbp) { struct mapinfo map; off_t curoff, size, lineend; @@ -132,7 +132,7 @@ r_reg(FILE *fp, enum STYLE style, off_t if (curoff < map.mapoff || curoff >= map.mapoff + (off_t)map.maplen) { if (maparound(&map, curoff) != 0) { - ierr(); + ierr(fn); return; } } @@ -149,7 +149,7 @@ r_reg(FILE *fp, enum STYLE style, off_t /* Print the line and update offsets. */ if (mapprint(&map, curoff + 1, lineend - curoff - 1) != 0) { - ierr(); + ierr(fn); return; } lineend = curoff + 1; @@ -165,11 +165,11 @@ r_reg(FILE *fp, enum STYLE style, off_t } } if (curoff < 0 && mapprint(&map, 0, lineend) != 0) { - ierr(); + ierr(fn); return; } if (map.start != NULL && munmap(map.start, map.maplen)) - ierr(); + ierr(fn); } typedef struct bf { @@ -190,7 +190,7 @@ typedef struct bf { * user warned). */ static void -r_buf(FILE *fp) +r_buf(FILE *fp, const char *fn) { BF *mark, *tl, *tr; int ch, len, llen; @@ -226,7 +226,7 @@ r_buf(FILE *fp) *p++ = ch; if (ferror(fp)) { - ierr(); + ierr(fn); return; } Modified: stable/7/usr.bin/tail/tail.1 ============================================================================== --- stable/7/usr.bin/tail/tail.1 Fri Jun 26 01:04:50 2009 (r195026) +++ stable/7/usr.bin/tail/tail.1 Fri Jun 26 01:08:35 2009 (r195027) @@ -35,7 +35,7 @@ .\" @(#)tail.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd June 29, 2006 +.Dd June 05, 2009 .Dt TAIL 1 .Os .Sh NAME @@ -106,9 +106,16 @@ will also check to see if the file being The file is closed and reopened when .Nm detects that the filename being read from has a new inode number. +.Pp +If the file being followed does not (yet) exist or if it is removed, tail +will keep looking and will display the file from the beginning if and when +it is created. +.Pp The .Fl F -option is ignored if reading from standard input rather than a file. +option is the same as the +.Fl f +option if reading from standard input rather than a file. .It Fl n Ar number The location is .Ar number Modified: stable/7/usr.bin/tail/tail.c ============================================================================== --- stable/7/usr.bin/tail/tail.c Fri Jun 26 01:04:50 2009 (r195026) +++ stable/7/usr.bin/tail/tail.c Fri Jun 26 01:08:35 2009 (r195027) @@ -61,7 +61,6 @@ static const char sccsid[] = "@(#)tail.c #include "extern.h" int Fflag, fflag, qflag, rflag, rval, no_files; -const char *fname; file_info_t *files; @@ -72,6 +71,7 @@ int main(int argc, char *argv[]) { struct stat sb; + const char *fn; FILE *fp; off_t off; enum STYLE style; @@ -174,20 +174,23 @@ main(int argc, char *argv[]) } if (*argv && fflag) { - files = (struct file_info *) malloc(no_files * sizeof(struct file_info)); - if (! files) + files = (struct file_info *) malloc(no_files * + sizeof(struct file_info)); + if (!files) err(1, "Couldn't malloc space for file descriptors."); - for (file = files; (fname = *argv++); file++) { - file->file_name = malloc(strlen(fname)+1); + for (file = files; (fn = *argv++); file++) { + file->file_name = strdup(fn); if (! file->file_name) errx(1, "Couldn't malloc space for file name."); - strncpy(file->file_name, fname, strlen(fname)+1); if ((file->fp = fopen(file->file_name, "r")) == NULL || fstat(fileno(file->fp), &file->st)) { - file->fp = NULL; - ierr(); - continue; + if (file->fp != NULL) { + fclose(file->fp); + file->fp = NULL; + } + if (!Fflag || errno != ENOENT) + ierr(file->file_name); } } follow(files, style, off); @@ -196,29 +199,29 @@ main(int argc, char *argv[]) } free(files); } else if (*argv) { - for (first = 1; (fname = *argv++);) { - if ((fp = fopen(fname, "r")) == NULL || + for (first = 1; (fn = *argv++);) { + if ((fp = fopen(fn, "r")) == NULL || fstat(fileno(fp), &sb)) { - ierr(); + ierr(fn); continue; } if (argc > 1 && !qflag) { (void)printf("%s==> %s <==\n", - first ? "" : "\n", fname); + first ? "" : "\n", fn); first = 0; (void)fflush(stdout); } if (rflag) - reverse(fp, style, off, &sb); + reverse(fp, fn, style, off, &sb); else - forward(fp, style, off, &sb); + forward(fp, fn, style, off, &sb); } } else { - fname = "stdin"; + fn = "stdin"; if (fstat(fileno(stdin), &sb)) { - ierr(); + ierr(fn); exit(1); } @@ -233,9 +236,9 @@ main(int argc, char *argv[]) } if (rflag) - reverse(stdin, style, off, &sb); + reverse(stdin, fn, style, off, &sb); else - forward(stdin, style, off, &sb); + forward(stdin, fn, style, off, &sb); } exit(rval); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906260108.n5Q18ZBs070148>