aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-07-02 20:09:15 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2013-07-02 20:09:15 +0200
commit6651e4260955d159e6a4f794d0a69c1b3f8e670c (patch)
treeee1417b778865b3115a12f4e1295f90cea7d50f5
parentcd8eece88ed6da58209a18a8c3edac73eab27e1c (diff)
downloadbusybox-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.c26
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
69static ssize_t tail_read(int fd, char *buf, size_t count) 69static 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;