Change tail to use kqueue/kevent to obtain a notification when
the file changes (when doing tail -{f|F}).
This commit is contained in:
parent
3ee12e4fe3
commit
b446630f2f
@ -32,6 +32,8 @@
|
|||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
* 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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
@ -43,6 +45,7 @@ static char sccsid[] = "@(#)forward.c 8.1 (Berkeley) 6/6/93";
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <event.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -84,9 +87,8 @@ forward(fp, style, off, sbp)
|
|||||||
long off;
|
long off;
|
||||||
struct stat *sbp;
|
struct stat *sbp;
|
||||||
{
|
{
|
||||||
register int ch;
|
int ch, add_events = 0, kq = -1;
|
||||||
struct timeval interval;
|
struct kevent ev[2];
|
||||||
struct stat sb2;
|
|
||||||
|
|
||||||
switch(style) {
|
switch(style) {
|
||||||
case FBYTES:
|
case FBYTES:
|
||||||
@ -161,10 +163,12 @@ forward(fp, style, off, sbp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (fflag) {
|
||||||
* We pause for 1/4 second after displaying any data that has
|
kq = kqueue();
|
||||||
* accumulated since we read the file.
|
if (kq < 0)
|
||||||
*/
|
err(1, "kqueue");
|
||||||
|
add_events = 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while ((ch = getc(fp)) != EOF)
|
while ((ch = getc(fp)) != EOF)
|
||||||
@ -175,24 +179,49 @@ forward(fp, style, off, sbp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(void)fflush(stdout);
|
(void)fflush(stdout);
|
||||||
if (!fflag)
|
if (! fflag)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
(void) usleep(250000);
|
|
||||||
clearerr(fp);
|
clearerr(fp);
|
||||||
|
|
||||||
if (Fflag && fileno(fp) != STDIN_FILENO &&
|
if (add_events) {
|
||||||
stat(fname, &sb2) != -1) {
|
int n = 0;
|
||||||
if (sb2.st_ino != sbp->st_ino ||
|
struct kevent *evp[2];
|
||||||
sb2.st_dev != sbp->st_dev ||
|
struct timespec ts = { 0, 0 };
|
||||||
sb2.st_rdev != sbp->st_rdev ||
|
|
||||||
sb2.st_nlink == 0) {
|
if (Fflag && fileno(fp) != STDIN_FILENO) {
|
||||||
fp = freopen(fname, "r", fp);
|
ev[n].ident = fileno(fp);
|
||||||
if (fp == NULL) {
|
ev[n].filter = EVFILT_VNODE;
|
||||||
ierr();
|
ev[n].flags = EV_ADD | EV_ENABLE | EV_CLEAR;
|
||||||
break;
|
ev[n].fflags = NOTE_DELETE | NOTE_RENAME;
|
||||||
}
|
evp[n] = &ev[n];
|
||||||
*sbp = sb2;
|
n++;
|
||||||
|
}
|
||||||
|
ev[n].ident = fileno(fp);
|
||||||
|
ev[n].filter = EVFILT_READ;
|
||||||
|
ev[n].flags = EV_ADD | EV_ENABLE;
|
||||||
|
evp[n] = &ev[n];
|
||||||
|
n++;
|
||||||
|
|
||||||
|
if (kevent(kq, n, evp, 0, NULL, &ts) < 0)
|
||||||
|
err(1, "kevent");
|
||||||
|
add_events = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
add_events = 1;
|
||||||
|
} else if (ev->data < 0) {
|
||||||
|
/* file shrank, reposition to end */
|
||||||
|
if (fseek(fp, 0L, SEEK_END) == -1) {
|
||||||
|
ierr();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user