diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-05-20 00:30:04 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-05-20 00:30:04 +0200 |
| commit | 9e933d9bfc7f52a7d8bc61805f70e3039b30216f (patch) | |
| tree | 714c2feff4c578b80f3af56e6fb6ee9fdedd3e83 /coreutils | |
| parent | 24b71fd8948fda65bbcf3df90f3eb143202be4e3 (diff) | |
| download | busybox-w32-9e933d9bfc7f52a7d8bc61805f70e3039b30216f.tar.gz busybox-w32-9e933d9bfc7f52a7d8bc61805f70e3039b30216f.tar.bz2 busybox-w32-9e933d9bfc7f52a7d8bc61805f70e3039b30216f.zip | |
tail: optimize "tail -c HUGENUM REGULAR_FILE". Closes 3763.
function old new delta
tail_main 1541 1547 +6
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/tail.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/coreutils/tail.c b/coreutils/tail.c index eac982735..4b42ebc52 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
| @@ -59,7 +59,8 @@ static const struct suffix_mult tail_suffixes[] = { | |||
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | struct globals { | 61 | struct globals { |
| 62 | bool status; | 62 | bool from_top; |
| 63 | bool exitcode; | ||
| 63 | } FIX_ALIASING; | 64 | } FIX_ALIASING; |
| 64 | #define G (*(struct globals*)&bb_common_bufsiz1) | 65 | #define G (*(struct globals*)&bb_common_bufsiz1) |
| 65 | 66 | ||
| @@ -85,7 +86,7 @@ static ssize_t tail_read(int fd, char *buf, size_t count) | |||
| 85 | r = full_read(fd, buf, count); | 86 | r = full_read(fd, buf, count); |
| 86 | if (r < 0) { | 87 | if (r < 0) { |
| 87 | bb_perror_msg(bb_msg_read_error); | 88 | bb_perror_msg(bb_msg_read_error); |
| 88 | G.status = EXIT_FAILURE; | 89 | G.exitcode = EXIT_FAILURE; |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | return r; | 92 | return r; |
| @@ -99,7 +100,7 @@ static unsigned eat_num(const char *p) | |||
| 99 | p++; | 100 | p++; |
| 100 | else if (*p == '+') { | 101 | else if (*p == '+') { |
| 101 | p++; | 102 | p++; |
| 102 | G.status = 1; /* mark that we saw "+" */ | 103 | G.from_top = 1; |
| 103 | } | 104 | } |
| 104 | return xatou_sfx(p, tail_suffixes); | 105 | return xatou_sfx(p, tail_suffixes); |
| 105 | } | 106 | } |
| @@ -109,7 +110,6 @@ int tail_main(int argc, char **argv) | |||
| 109 | { | 110 | { |
| 110 | unsigned count = 10; | 111 | unsigned count = 10; |
| 111 | unsigned sleep_period = 1; | 112 | unsigned sleep_period = 1; |
| 112 | bool from_top; | ||
| 113 | const char *str_c, *str_n; | 113 | const char *str_c, *str_n; |
| 114 | 114 | ||
| 115 | char *tailbuf; | 115 | char *tailbuf; |
| @@ -152,8 +152,6 @@ int tail_main(int argc, char **argv) | |||
| 152 | #endif | 152 | #endif |
| 153 | argc -= optind; | 153 | argc -= optind; |
| 154 | argv += optind; | 154 | argv += optind; |
| 155 | from_top = G.status; /* 1 if there was "-c +N" or "-n +N" */ | ||
| 156 | G.status = EXIT_SUCCESS; | ||
| 157 | 155 | ||
| 158 | /* open all the files */ | 156 | /* open all the files */ |
| 159 | fds = xmalloc(sizeof(fds[0]) * (argc + 1)); | 157 | fds = xmalloc(sizeof(fds[0]) * (argc + 1)); |
| @@ -171,7 +169,7 @@ int tail_main(int argc, char **argv) | |||
| 171 | do { | 169 | do { |
| 172 | int fd = open_or_warn_stdin(argv[i]); | 170 | int fd = open_or_warn_stdin(argv[i]); |
| 173 | if (fd < 0 && !FOLLOW_RETRY) { | 171 | if (fd < 0 && !FOLLOW_RETRY) { |
| 174 | G.status = EXIT_FAILURE; | 172 | G.exitcode = EXIT_FAILURE; |
| 175 | continue; | 173 | continue; |
| 176 | } | 174 | } |
| 177 | fds[nfiles] = fd; | 175 | fds[nfiles] = fd; |
| @@ -183,15 +181,19 @@ int tail_main(int argc, char **argv) | |||
| 183 | 181 | ||
| 184 | /* prepare the buffer */ | 182 | /* prepare the buffer */ |
| 185 | tailbufsize = BUFSIZ; | 183 | tailbufsize = BUFSIZ; |
| 186 | if (!from_top && COUNT_BYTES) { | 184 | if (!G.from_top && COUNT_BYTES) { |
| 187 | if (tailbufsize < count + BUFSIZ) { | 185 | if (tailbufsize < count + BUFSIZ) { |
| 188 | tailbufsize = count + BUFSIZ; | 186 | tailbufsize = count + BUFSIZ; |
| 189 | } | 187 | } |
| 190 | } | 188 | } |
| 191 | tailbuf = xmalloc(tailbufsize); | 189 | /* tail -c1024m REGULAR_FILE doesn't really need 1G mem block. |
| 190 | * (In fact, it doesn't need ANY memory). So delay allocation. | ||
| 191 | */ | ||
| 192 | tailbuf = NULL; | ||
| 192 | 193 | ||
| 193 | /* tail the files */ | 194 | /* tail the files */ |
| 194 | fmt = header_fmt_str + 1; /* skip header leading newline on first output */ | 195 | |
| 196 | fmt = header_fmt_str + 1; /* skip leading newline in the header on the first output */ | ||
| 195 | i = 0; | 197 | i = 0; |
| 196 | do { | 198 | do { |
| 197 | char *buf; | 199 | char *buf; |
| @@ -209,7 +211,7 @@ int tail_main(int argc, char **argv) | |||
| 209 | fmt = header_fmt_str; | 211 | fmt = header_fmt_str; |
| 210 | } | 212 | } |
| 211 | 213 | ||
| 212 | if (!from_top) { | 214 | if (!G.from_top) { |
| 213 | off_t current = lseek(fd, 0, SEEK_END); | 215 | off_t current = lseek(fd, 0, SEEK_END); |
| 214 | if (current > 0) { | 216 | if (current > 0) { |
| 215 | unsigned off; | 217 | unsigned off; |
| @@ -242,6 +244,9 @@ int tail_main(int argc, char **argv) | |||
| 242 | } | 244 | } |
| 243 | } | 245 | } |
| 244 | 246 | ||
| 247 | if (!tailbuf) | ||
| 248 | tailbuf = xmalloc(tailbufsize); | ||
| 249 | |||
| 245 | buf = tailbuf; | 250 | buf = tailbuf; |
| 246 | taillen = 0; | 251 | taillen = 0; |
| 247 | /* "We saw 1st line/byte". | 252 | /* "We saw 1st line/byte". |
| @@ -249,7 +254,7 @@ int tail_main(int argc, char **argv) | |||
| 249 | seen = 1; | 254 | seen = 1; |
| 250 | newlines_seen = 0; | 255 | newlines_seen = 0; |
| 251 | while ((nread = tail_read(fd, buf, tailbufsize-taillen)) > 0) { | 256 | while ((nread = tail_read(fd, buf, tailbufsize-taillen)) > 0) { |
| 252 | if (from_top) { | 257 | if (G.from_top) { |
| 253 | int nwrite = nread; | 258 | int nwrite = nread; |
| 254 | if (seen < count) { | 259 | if (seen < count) { |
| 255 | /* We need to skip a few more bytes/lines */ | 260 | /* We need to skip a few more bytes/lines */ |
| @@ -313,7 +318,7 @@ int tail_main(int argc, char **argv) | |||
| 313 | buf = tailbuf + taillen; | 318 | buf = tailbuf + taillen; |
| 314 | } | 319 | } |
| 315 | } /* while (tail_read() > 0) */ | 320 | } /* while (tail_read() > 0) */ |
| 316 | if (!from_top) { | 321 | if (!G.from_top) { |
| 317 | xwrite(STDOUT_FILENO, tailbuf, taillen); | 322 | xwrite(STDOUT_FILENO, tailbuf, taillen); |
| 318 | } | 323 | } |
| 319 | } while (++i < nfiles); | 324 | } while (++i < nfiles); |
| @@ -368,10 +373,11 @@ int tail_main(int argc, char **argv) | |||
| 368 | xwrite(STDOUT_FILENO, tailbuf, nread); | 373 | xwrite(STDOUT_FILENO, tailbuf, nread); |
| 369 | } | 374 | } |
| 370 | } while (++i < nfiles); | 375 | } while (++i < nfiles); |
| 371 | } | 376 | } /* while (1) */ |
| 377 | |||
| 372 | if (ENABLE_FEATURE_CLEAN_UP) { | 378 | if (ENABLE_FEATURE_CLEAN_UP) { |
| 373 | free(fds); | 379 | free(fds); |
| 374 | free(tailbuf); | 380 | free(tailbuf); |
| 375 | } | 381 | } |
| 376 | return G.status; | 382 | return G.exitcode; |
| 377 | } | 383 | } |
