summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Lemon <jlemon@FreeBSD.org>2000-06-22 18:46:03 +0000
committerJonathan Lemon <jlemon@FreeBSD.org>2000-06-22 18:46:03 +0000
commitea9bd2df1d0f770b1d7bdffcb1e9104abf0bc679 (patch)
treed693b550973eef086806194baf5a775935942eab
parentc8bea19ee361da93b051bf859b1e87f1559681c5 (diff)
Notes
-rw-r--r--usr.bin/tail/forward.c72
1 files changed, 53 insertions, 19 deletions
diff --git a/usr.bin/tail/forward.c b/usr.bin/tail/forward.c
index 5fff64f2affd..526ff2f6e363 100644
--- a/usr.bin/tail/forward.c
+++ b/usr.bin/tail/forward.c
@@ -58,6 +58,11 @@ static char sccsid[] = "@(#)forward.c 8.1 (Berkeley) 6/6/93";
static void rlines __P((FILE *, long, struct stat *));
+/* defines for inner loop actions */
+#define USE_SLEEP 0
+#define USE_KQUEUE 1
+#define ADD_EVENTS 2
+
/*
* forward -- display the file, from an offset, forward.
*
@@ -87,8 +92,10 @@ forward(fp, style, off, sbp)
long off;
struct stat *sbp;
{
- int ch, add_events = 0, kq = -1;
+ int ch, kq = -1;
+ int action = USE_SLEEP;
struct kevent ev[2];
+ struct stat sb2;
switch(style) {
case FBYTES:
@@ -167,7 +174,7 @@ forward(fp, style, off, sbp)
kq = kqueue();
if (kq < 0)
err(1, "kqueue");
- add_events = 1;
+ action = ADD_EVENTS;
}
for (;;) {
@@ -183,7 +190,8 @@ forward(fp, style, off, sbp)
break;
clearerr(fp);
- if (add_events) {
+ switch (action) {
+ case ADD_EVENTS: {
int n = 0;
struct kevent *evp[2];
struct timespec ts = { 0, 0 };
@@ -202,27 +210,53 @@ forward(fp, style, off, sbp)
evp[n] = &ev[n];
n++;
- if (kevent(kq, n, evp, 0, NULL, &ts) < 0)
- err(1, "kevent");
- add_events = 0;
+ if (kevent(kq, n, evp, 0, NULL, &ts) < 0) {
+ close(kq);
+ kq = -1;
+ action = USE_SLEEP;
+ } else {
+ action = USE_KQUEUE;
+ }
+ break;
}
- if (kevent(kq, 0, NULL, 1, ev, NULL) < 0)
- err(1, "kevent");
+ case USE_KQUEUE:
+ if (kevent(kq, 0, NULL, 1, ev, NULL) < 0)
+ err(1, "kevent");
- if (ev->filter == EVFILT_VNODE) {
- fp = freopen(fname, "r", fp);
- if (fp == NULL) {
- ierr();
- break;
+ if (ev->filter == EVFILT_VNODE) {
+ /* file was rotated, wait until it reappears */
+ action = USE_SLEEP;
+ } else if (ev->data < 0) {
+ /* file shrank, reposition to end */
+ if (fseek(fp, 0L, SEEK_END) == -1) {
+ ierr();
+ return;
+ }
}
- add_events = 1;
- } else if (ev->data < 0) {
- /* file shrank, reposition to end */
- if (fseek(fp, 0L, SEEK_END) == -1) {
- ierr();
- return;
+ break;
+
+ case USE_SLEEP:
+ (void) usleep(250000);
+ clearerr(fp);
+
+ if (Fflag && fileno(fp) != STDIN_FILENO &&
+ stat(fname, &sb2) != -1) {
+ if (sb2.st_ino != sbp->st_ino ||
+ sb2.st_dev != sbp->st_dev ||
+ sb2.st_rdev != sbp->st_rdev ||
+ sb2.st_nlink == 0) {
+ fp = freopen(fname, "r", fp);
+ if (fp == NULL) {
+ ierr();
+ break;
+ }
+ *sbp = sb2;
+ if (kq != -1)
+ action = ADD_EVENTS;
+ }
}
+ break;
}
}
}