diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-07-02 20:09:15 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-07-02 20:09:15 +0200 |
commit | 6651e4260955d159e6a4f794d0a69c1b3f8e670c (patch) | |
tree | ee1417b778865b3115a12f4e1295f90cea7d50f5 | |
parent | cd8eece88ed6da58209a18a8c3edac73eab27e1c (diff) | |
download | busybox-w32-6651e4260955d159e6a4f794d0a69c1b3f8e670c.tar.gz busybox-w32-6651e4260955d159e6a4f794d0a69c1b3f8e670c.tar.bz2 busybox-w32-6651e4260955d159e6a4f794d0a69c1b3f8e670c.zip |
tail: track file size only in -f mode
This eliminates extra fstat and lseek calls on every read
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | coreutils/tail.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/coreutils/tail.c b/coreutils/tail.c index 19fd8f695..fb07ca27b 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
@@ -66,17 +66,21 @@ static void tail_xprint_header(const char *fmt, const char *filename) | |||
66 | bb_perror_nomsg_and_die(); | 66 | bb_perror_nomsg_and_die(); |
67 | } | 67 | } |
68 | 68 | ||
69 | static ssize_t tail_read(int fd, char *buf, size_t count) | 69 | static ssize_t tail_read(int fd, char *buf, size_t count, int follow) |
70 | { | 70 | { |
71 | ssize_t r; | 71 | ssize_t r; |
72 | off_t current; | 72 | |
73 | struct stat sbuf; | 73 | if (follow) { |
74 | 74 | /* tail -f keeps following files even if they are truncated */ | |
75 | /* /proc files report zero st_size, don't lseek them. */ | 75 | off_t current; |
76 | if (fstat(fd, &sbuf) == 0 && sbuf.st_size > 0) { | 76 | struct stat sbuf; |
77 | current = lseek(fd, 0, SEEK_CUR); | 77 | |
78 | if (sbuf.st_size < current) | 78 | /* /proc files report zero st_size, don't lseek them */ |
79 | xlseek(fd, 0, SEEK_SET); | 79 | if (fstat(fd, &sbuf) == 0 && sbuf.st_size > 0) { |
80 | current = lseek(fd, 0, SEEK_CUR); | ||
81 | if (sbuf.st_size < current) | ||
82 | xlseek(fd, 0, SEEK_SET); | ||
83 | } | ||
80 | } | 84 | } |
81 | 85 | ||
82 | r = full_read(fd, buf, count); | 86 | r = full_read(fd, buf, count); |
@@ -251,7 +255,7 @@ int tail_main(int argc, char **argv) | |||
251 | * Used only by +N code ("start from Nth", 1-based): */ | 255 | * Used only by +N code ("start from Nth", 1-based): */ |
252 | seen = 1; | 256 | seen = 1; |
253 | newlines_seen = 0; | 257 | newlines_seen = 0; |
254 | while ((nread = tail_read(fd, buf, tailbufsize - taillen)) > 0) { | 258 | while ((nread = tail_read(fd, buf, tailbufsize - taillen, /*follow:*/ 0)) > 0) { |
255 | if (G.from_top) { | 259 | if (G.from_top) { |
256 | int nwrite = nread; | 260 | int nwrite = nread; |
257 | if (seen < count) { | 261 | if (seen < count) { |
@@ -363,7 +367,7 @@ int tail_main(int argc, char **argv) | |||
363 | if (nfiles > header_threshhold) { | 367 | if (nfiles > header_threshhold) { |
364 | fmt = header_fmt_str; | 368 | fmt = header_fmt_str; |
365 | } | 369 | } |
366 | while ((nread = tail_read(fd, tailbuf, BUFSIZ)) > 0) { | 370 | while ((nread = tail_read(fd, tailbuf, BUFSIZ, /*follow:*/ 1)) > 0) { |
367 | if (fmt) { | 371 | if (fmt) { |
368 | tail_xprint_header(fmt, filename); | 372 | tail_xprint_header(fmt, filename); |
369 | fmt = NULL; | 373 | fmt = NULL; |