diff options
author | Denys Vlasenko | 2021-06-02 04:55:10 +0200 |
---|---|---|
committer | Denys Vlasenko | 2021-06-02 05:17:44 +0200 |
commit | f193aeac1fe27c94d0f0b27314777df41480feb6 (patch) | |
tree | 9a21f60faa1a4a803fb9a60284a7d57d1c559834 /coreutils | |
parent | e0ea125ce24ebdd1febf930fca436f1a8fb7d48d (diff) | |
download | busybox-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>
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/tail.c | 38 |
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; |