diff options
| -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; |
