svn commit: r195027 - stable/7/usr.bin/tail
Brian Somers
brian at FreeBSD.org
Fri Jun 26 01:08:37 UTC 2009
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);
}
More information about the svn-src-stable-7
mailing list