diff options
| author | Jonathan Lemon <jlemon@FreeBSD.org> | 2000-07-18 21:49:41 +0000 |
|---|---|---|
| committer | Jonathan Lemon <jlemon@FreeBSD.org> | 2000-07-18 21:49:41 +0000 |
| commit | bd175b9445edc838500c44fcaf962a35545dce24 (patch) | |
| tree | 26603601e18983146e09d716bd9eada4355b42a5 /usr.bin | |
| parent | 25ccfd73ddb03b1267c38bfbc2b4a98538b9e167 (diff) | |
Notes
Diffstat (limited to 'usr.bin')
| -rw-r--r-- | usr.bin/tail/forward.c | 98 |
1 files changed, 79 insertions, 19 deletions
diff --git a/usr.bin/tail/forward.c b/usr.bin/tail/forward.c index 31f5ea66fc16..a864eddb4839 100644 --- a/usr.bin/tail/forward.c +++ b/usr.bin/tail/forward.c @@ -32,6 +32,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ #ifndef lint @@ -42,6 +44,7 @@ static char sccsid[] = "@(#)forward.c 8.1 (Berkeley) 6/6/93"; #include <sys/stat.h> #include <sys/time.h> #include <sys/mman.h> +#include <sys/event.h> #include <limits.h> #include <fcntl.h> @@ -55,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. * @@ -84,8 +92,9 @@ forward(fp, style, off, sbp) long off; struct stat *sbp; { - register int ch; - struct timeval interval; + int ch, kq = -1; + int action = USE_SLEEP; + struct kevent ev[2]; struct stat sb2; switch(style) { @@ -161,10 +170,12 @@ forward(fp, style, off, sbp) break; } - /* - * We pause for 1/4 second after displaying any data that has - * accumulated since we read the file. - */ + if (fflag) { + kq = kqueue(); + if (kq < 0) + err(1, "kqueue"); + action = ADD_EVENTS; + } for (;;) { while ((ch = getc(fp)) != EOF) @@ -175,25 +186,74 @@ forward(fp, style, off, sbp) return; } (void)fflush(stdout); - if (!fflag) + if (! fflag) break; - - (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) { + switch (action) { + case ADD_EVENTS: { + int n = 0; + struct timespec ts = { 0, 0 }; + + if (Fflag && fileno(fp) != STDIN_FILENO) { + ev[n].ident = fileno(fp); + ev[n].filter = EVFILT_VNODE; + ev[n].flags = EV_ADD | EV_ENABLE | EV_CLEAR; + ev[n].fflags = NOTE_DELETE | NOTE_RENAME; + n++; + } + ev[n].ident = fileno(fp); + ev[n].filter = EVFILT_READ; + ev[n].flags = EV_ADD | EV_ENABLE; + n++; + + if (kevent(kq, ev, n, NULL, 0, &ts) < 0) { + close(kq); + kq = -1; + action = USE_SLEEP; + } else { + action = USE_KQUEUE; + } + break; + } + + case USE_KQUEUE: + if (kevent(kq, NULL, 0, ev, 1, NULL) < 0) + err(1, "kevent"); + + 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(); - break; + 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; } - *sbp = sb2; } + break; } } } |
