summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2021-06-02 04:55:10 +0200
committerDenys Vlasenko2021-06-02 05:17:44 +0200
commitf193aeac1fe27c94d0f0b27314777df41480feb6 (patch)
tree9a21f60faa1a4a803fb9a60284a7d57d1c559834
parente0ea125ce24ebdd1febf930fca436f1a8fb7d48d (diff)
downloadbusybox-f193aeac1fe27c94d0f0b27314777df41480feb6.zip
busybox-f193aeac1fe27c94d0f0b27314777df41480feb6.tar.gz
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>
-rw-r--r--coreutils/tail.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/coreutils/tail.c b/coreutils/tail.c
index 93f1514..6201eb0 100644
--- a/coreutils/tail.c
+++ b/coreutils/tail.c
@@ -346,9 +346,11 @@ int tail_main(int argc, char **argv)
int nread;
const char *filename = argv[i];
int fd = fds[i];
+ int new_fd = -1;
+ struct stat sbuf;
if (FOLLOW_RETRY) {
- struct stat sbuf, fsbuf;
+ struct stat fsbuf;
if (fd < 0
|| fstat(fd, &fsbuf) < 0
@@ -356,19 +358,21 @@ int tail_main(int argc, char **argv)
|| fsbuf.st_dev != sbuf.st_dev
|| fsbuf.st_ino != sbuf.st_ino
) {
- int new_fd;
-
- if (fd >= 0)
- close(fd);
+ /* Looks like file has been created/renamed/deleted */
new_fd = open(filename, O_RDONLY);
if (new_fd >= 0) {
bb_error_msg("%s has %s; following end of new file",
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) {
- 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)
@@ -378,17 +382,27 @@ int tail_main(int argc, char **argv)
}
for (;;) {
/* tail -f keeps following files even if they are truncated */
- struct stat sbuf;
/* /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);
- 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);
+ }
}
nread = tail_read(fd, tailbuf, BUFSIZ);
- if (nread <= 0)
- break;
+ if (nread <= 0) {
+ 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)) {
tail_xprint_header(fmt, filename);
fmt = NULL;