diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-02 04:55:10 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-02 05:17:44 +0200 |
commit | f193aeac1fe27c94d0f0b27314777df41480feb6 (patch) | |
tree | 9a21f60faa1a4a803fb9a60284a7d57d1c559834 | |
parent | e0ea125ce24ebdd1febf930fca436f1a8fb7d48d (diff) | |
download | busybox-w32-f193aeac1fe27c94d0f0b27314777df41480feb6.tar.gz busybox-w32-f193aeac1fe27c94d0f0b27314777df41480feb6.tar.bz2 busybox-w32-f193aeac1fe27c94d0f0b27314777df41480feb6.zip |
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.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/coreutils/tail.c b/coreutils/tail.c index 93f1514d0..6201eb023 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
@@ -346,9 +346,11 @@ int tail_main(int argc, char **argv) | |||
346 | int nread; | 346 | int nread; |
347 | const char *filename = argv[i]; | 347 | const char *filename = argv[i]; |
348 | int fd = fds[i]; | 348 | int fd = fds[i]; |
349 | int new_fd = -1; | ||
350 | struct stat sbuf; | ||
349 | 351 | ||
350 | if (FOLLOW_RETRY) { | 352 | if (FOLLOW_RETRY) { |
351 | struct stat sbuf, fsbuf; | 353 | struct stat fsbuf; |
352 | 354 | ||
353 | if (fd < 0 | 355 | if (fd < 0 |
354 | || fstat(fd, &fsbuf) < 0 | 356 | || fstat(fd, &fsbuf) < 0 |
@@ -356,19 +358,21 @@ int tail_main(int argc, char **argv) | |||
356 | || fsbuf.st_dev != sbuf.st_dev | 358 | || fsbuf.st_dev != sbuf.st_dev |
357 | || fsbuf.st_ino != sbuf.st_ino | 359 | || fsbuf.st_ino != sbuf.st_ino |
358 | ) { | 360 | ) { |
359 | int new_fd; | 361 | /* Looks like file has been created/renamed/deleted */ |
360 | |||
361 | if (fd >= 0) | ||
362 | close(fd); | ||
363 | new_fd = open(filename, O_RDONLY); | 362 | new_fd = open(filename, O_RDONLY); |
364 | if (new_fd >= 0) { | 363 | if (new_fd >= 0) { |
365 | bb_error_msg("%s has %s; following end of new file", | 364 | bb_error_msg("%s has %s; following end of new file", |
366 | filename, (fd < 0) ? "appeared" : "been replaced" | 365 | filename, (fd < 0) ? "appeared" : "been replaced" |
367 | ); | 366 | ); |
367 | if (fd < 0) { | ||
368 | /* No previously open fd for this file, | ||
369 | * start using new_fd immediately. */ | ||
370 | fds[i] = fd = new_fd; | ||
371 | new_fd = -1; | ||
372 | } | ||
368 | } else if (fd >= 0) { | 373 | } else if (fd >= 0) { |
369 | bb_perror_msg("%s has become inaccessible", filename); | 374 | bb_perror_msg("%s has been renamed or deleted", filename); |
370 | } | 375 | } |
371 | fds[i] = fd = new_fd; | ||
372 | } | 376 | } |
373 | } | 377 | } |
374 | if (ENABLE_FEATURE_FANCY_TAIL && fd < 0) | 378 | if (ENABLE_FEATURE_FANCY_TAIL && fd < 0) |
@@ -378,17 +382,27 @@ int tail_main(int argc, char **argv) | |||
378 | } | 382 | } |
379 | for (;;) { | 383 | for (;;) { |
380 | /* tail -f keeps following files even if they are truncated */ | 384 | /* tail -f keeps following files even if they are truncated */ |
381 | struct stat sbuf; | ||
382 | /* /proc files report zero st_size, don't lseek them */ | 385 | /* /proc files report zero st_size, don't lseek them */ |
383 | if (fstat(fd, &sbuf) == 0 && sbuf.st_size > 0) { | 386 | if (fstat(fd, &sbuf) == 0 |
387 | /* && S_ISREG(sbuf.st_mode) TODO? */ | ||
388 | && sbuf.st_size > 0 | ||
389 | ) { | ||
384 | off_t current = lseek(fd, 0, SEEK_CUR); | 390 | off_t current = lseek(fd, 0, SEEK_CUR); |
385 | if (sbuf.st_size < current) | 391 | if (sbuf.st_size < current) { |
392 | //bb_perror_msg("%s: file truncated", filename); - says coreutils 8.32 | ||
386 | xlseek(fd, 0, SEEK_SET); | 393 | xlseek(fd, 0, SEEK_SET); |
394 | } | ||
387 | } | 395 | } |
388 | 396 | ||
389 | nread = tail_read(fd, tailbuf, BUFSIZ); | 397 | nread = tail_read(fd, tailbuf, BUFSIZ); |
390 | if (nread <= 0) | 398 | if (nread <= 0) { |
391 | break; | 399 | if (new_fd < 0) |
400 | break; | ||
401 | /* Switch to "tail -F"ing the new file */ | ||
402 | xmove_fd(new_fd, fd); | ||
403 | new_fd = -1; | ||
404 | continue; | ||
405 | } | ||
392 | if (fmt && (fd != prev_fd)) { | 406 | if (fmt && (fd != prev_fd)) { |
393 | tail_xprint_header(fmt, filename); | 407 | tail_xprint_header(fmt, filename); |
394 | fmt = NULL; | 408 | fmt = NULL; |