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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to