tail: do not lose the tail of old file if new file (-F) is detected
function old new delta tail_main 1619 1645 +26 .rodata 103246 103250 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 30/0) Total: 30 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
e0ea125ce2
commit
f193aeac1f
@ -346,9 +346,11 @@ int tail_main(int argc, char **argv)
|
|||||||
int nread;
|
int nread;
|
||||||
const char *filename = argv[i];
|
const char *filename = argv[i];
|
||||||
int fd = fds[i];
|
int fd = fds[i];
|
||||||
|
int new_fd = -1;
|
||||||
|
struct stat sbuf;
|
||||||
|
|
||||||
if (FOLLOW_RETRY) {
|
if (FOLLOW_RETRY) {
|
||||||
struct stat sbuf, fsbuf;
|
struct stat fsbuf;
|
||||||
|
|
||||||
if (fd < 0
|
if (fd < 0
|
||||||
|| fstat(fd, &fsbuf) < 0
|
|| fstat(fd, &fsbuf) < 0
|
||||||
@ -356,19 +358,21 @@ int tail_main(int argc, char **argv)
|
|||||||
|| fsbuf.st_dev != sbuf.st_dev
|
|| fsbuf.st_dev != sbuf.st_dev
|
||||||
|| fsbuf.st_ino != sbuf.st_ino
|
|| fsbuf.st_ino != sbuf.st_ino
|
||||||
) {
|
) {
|
||||||
int new_fd;
|
/* Looks like file has been created/renamed/deleted */
|
||||||
|
|
||||||
if (fd >= 0)
|
|
||||||
close(fd);
|
|
||||||
new_fd = open(filename, O_RDONLY);
|
new_fd = open(filename, O_RDONLY);
|
||||||
if (new_fd >= 0) {
|
if (new_fd >= 0) {
|
||||||
bb_error_msg("%s has %s; following end of new file",
|
bb_error_msg("%s has %s; following end of new file",
|
||||||
filename, (fd < 0) ? "appeared" : "been replaced"
|
filename, (fd < 0) ? "appeared" : "been replaced"
|
||||||
);
|
);
|
||||||
|
if (fd < 0) {
|
||||||
|
/* No previously open fd for this file,
|
||||||
|
* start using new_fd immediately. */
|
||||||
|
fds[i] = fd = new_fd;
|
||||||
|
new_fd = -1;
|
||||||
|
}
|
||||||
} else if (fd >= 0) {
|
} else if (fd >= 0) {
|
||||||
bb_perror_msg("%s has become inaccessible", filename);
|
bb_perror_msg("%s has been renamed or deleted", filename);
|
||||||
}
|
}
|
||||||
fds[i] = fd = new_fd;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ENABLE_FEATURE_FANCY_TAIL && fd < 0)
|
if (ENABLE_FEATURE_FANCY_TAIL && fd < 0)
|
||||||
@ -378,17 +382,27 @@ int tail_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* tail -f keeps following files even if they are truncated */
|
/* tail -f keeps following files even if they are truncated */
|
||||||
struct stat sbuf;
|
|
||||||
/* /proc files report zero st_size, don't lseek them */
|
/* /proc files report zero st_size, don't lseek them */
|
||||||
if (fstat(fd, &sbuf) == 0 && sbuf.st_size > 0) {
|
if (fstat(fd, &sbuf) == 0
|
||||||
|
/* && S_ISREG(sbuf.st_mode) TODO? */
|
||||||
|
&& sbuf.st_size > 0
|
||||||
|
) {
|
||||||
off_t current = lseek(fd, 0, SEEK_CUR);
|
off_t current = lseek(fd, 0, SEEK_CUR);
|
||||||
if (sbuf.st_size < current)
|
if (sbuf.st_size < current) {
|
||||||
|
//bb_perror_msg("%s: file truncated", filename); - says coreutils 8.32
|
||||||
xlseek(fd, 0, SEEK_SET);
|
xlseek(fd, 0, SEEK_SET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nread = tail_read(fd, tailbuf, BUFSIZ);
|
nread = tail_read(fd, tailbuf, BUFSIZ);
|
||||||
if (nread <= 0)
|
if (nread <= 0) {
|
||||||
break;
|
if (new_fd < 0)
|
||||||
|
break;
|
||||||
|
/* Switch to "tail -F"ing the new file */
|
||||||
|
xmove_fd(new_fd, fd);
|
||||||
|
new_fd = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (fmt && (fd != prev_fd)) {
|
if (fmt && (fd != prev_fd)) {
|
||||||
tail_xprint_header(fmt, filename);
|
tail_xprint_header(fmt, filename);
|
||||||
fmt = NULL;
|
fmt = NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user