version 1.11, 2000/11/21 22:01:47 |
version 1.12, 2001/08/18 14:49:15 |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
#include <sys/mman.h> |
#include <sys/mman.h> |
|
#include <sys/event.h> |
|
|
#include <err.h> |
#include <err.h> |
#include <errno.h> |
#include <errno.h> |
|
|
long off; |
long off; |
struct stat *sbp; |
struct stat *sbp; |
{ |
{ |
register int ch; |
int ch; |
struct stat nsb; |
struct stat nsb; |
|
int kq; |
|
struct kevent ke; |
|
|
switch(style) { |
switch(style) { |
case FBYTES: |
case FBYTES: |
|
|
break; |
break; |
} |
} |
|
|
|
kq = -1; |
|
kq_retry: |
|
if (fflag && ((kq = kqueue()) >= 0)) { |
|
ke.ident = fileno(fp); |
|
ke.flags = EV_ENABLE|EV_ADD|EV_CLEAR; |
|
ke.filter = EVFILT_READ; |
|
ke.fflags = ke.data = 0; |
|
ke.udata = NULL; |
|
if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) { |
|
close(kq); |
|
kq = -1; |
|
} else if (S_ISREG(sbp->st_mode)) { |
|
ke.ident = fileno(fp); |
|
ke.flags = EV_ENABLE|EV_ADD|EV_CLEAR; |
|
ke.filter = EVFILT_VNODE; |
|
ke.fflags = NOTE_DELETE | NOTE_RENAME; |
|
if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) { |
|
close(kq); |
|
kq = -1; |
|
} |
|
} |
|
} |
|
|
for (;;) { |
for (;;) { |
while (!feof(fp) && (ch = getc(fp)) != EOF) |
while (!feof(fp) && (ch = getc(fp)) != EOF) |
if (putchar(ch) == EOF) |
if (putchar(ch) == EOF) |
oerr(); |
oerr(); |
if (ferror(fp)) { |
if (ferror(fp)) { |
ierr(); |
ierr(); |
|
if (kq != -1) |
|
close(kq); |
return; |
return; |
} |
} |
(void)fflush(stdout); |
(void)fflush(stdout); |
if (!fflag) |
if (!fflag) |
break; |
break; |
sleep(1); |
|
clearerr(fp); |
clearerr(fp); |
|
if (kq < 0 || kevent(kq, NULL, 0, &ke, 1, NULL) <= 0) { |
|
sleep(1); |
|
} else if (ke.filter == EVFILT_READ) { |
|
continue; |
|
} else { |
|
/* |
|
* File was renamed or deleted. |
|
* |
|
* Continue to look at it until a new file reappears |
|
* with the same name. |
|
* Fall back to the old algorithm for that. |
|
*/ |
|
close(kq); |
|
kq = -1; |
|
} |
|
|
if (is_stdin || stat(fname, &nsb) != 0) |
if (is_stdin || stat(fname, &nsb) != 0) |
continue; |
continue; |
|
|
warnx("%s has been replaced, reopening.", fname); |
warnx("%s has been replaced, reopening.", fname); |
if ((fp = freopen(fname, "r", fp)) == NULL) { |
if ((fp = freopen(fname, "r", fp)) == NULL) { |
ierr(); |
ierr(); |
|
if (kq >= 0) |
|
close(kq); |
return; |
return; |
} |
} |
(void)memcpy(sbp, &nsb, sizeof(nsb)); |
(void)memcpy(sbp, &nsb, sizeof(nsb)); |
|
goto kq_retry; |
} else if (nsb.st_size < sbp->st_size) { |
} else if (nsb.st_size < sbp->st_size) { |
warnx("%s has been truncated, resetting.", fname); |
warnx("%s has been truncated, resetting.", fname); |
rewind(fp); |
rewind(fp); |
(void)memcpy(sbp, &nsb, sizeof(nsb)); |
(void)memcpy(sbp, &nsb, sizeof(nsb)); |
} |
} |
} |
} |
|
if (kq >= 0) |
|
close(kq); |
} |
} |
|
|
/* |
/* |