tail: fix "tail -c 20 /dev/huge_disk" (was taking ages)
tail: a few variables renamed wc: tiny optimization.
This commit is contained in:
parent
5233cd3800
commit
e8419c90f1
@ -74,7 +74,7 @@ static unsigned eat_num(const char *p)
|
|||||||
p++;
|
p++;
|
||||||
else if (*p == '+') {
|
else if (*p == '+') {
|
||||||
p++;
|
p++;
|
||||||
G.status = EXIT_FAILURE;
|
G.status = 1; /* mark that we saw "+" */
|
||||||
}
|
}
|
||||||
return xatou_sfx(p, tail_suffixes);
|
return xatou_sfx(p, tail_suffixes);
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ int tail_main(int argc, char **argv)
|
|||||||
char *tailbuf;
|
char *tailbuf;
|
||||||
size_t tailbufsize;
|
size_t tailbufsize;
|
||||||
int taillen = 0;
|
int taillen = 0;
|
||||||
int newline = 0;
|
int newlines_seen = 0;
|
||||||
int nfiles, nread, nwrite, seen, i, opt;
|
int nfiles, nread, nwrite, seen, i, opt;
|
||||||
|
|
||||||
int *fds;
|
int *fds;
|
||||||
@ -128,12 +128,12 @@ int tail_main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
from_top = G.status;
|
from_top = G.status; /* 1 if there was "-c +N" or "-n +N" */
|
||||||
|
G.status = EXIT_SUCCESS;
|
||||||
|
|
||||||
/* open all the files */
|
/* open all the files */
|
||||||
fds = xmalloc(sizeof(int) * (argc + 1));
|
fds = xmalloc(sizeof(int) * (argc + 1));
|
||||||
nfiles = i = 0;
|
nfiles = i = 0;
|
||||||
G.status = EXIT_SUCCESS;
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
@ -155,39 +155,49 @@ int tail_main(int argc, char **argv)
|
|||||||
if (!nfiles)
|
if (!nfiles)
|
||||||
bb_error_msg_and_die("no files");
|
bb_error_msg_and_die("no files");
|
||||||
|
|
||||||
|
/* prepare the buffer */
|
||||||
tailbufsize = BUFSIZ;
|
tailbufsize = BUFSIZ;
|
||||||
|
|
||||||
/* tail the files */
|
|
||||||
if (!from_top && COUNT_BYTES) {
|
if (!from_top && COUNT_BYTES) {
|
||||||
if (tailbufsize < count) {
|
if (tailbufsize < count + BUFSIZ) {
|
||||||
tailbufsize = count + BUFSIZ;
|
tailbufsize = count + BUFSIZ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tailbuf = xmalloc(tailbufsize);
|
||||||
|
|
||||||
buf = tailbuf = xmalloc(tailbufsize);
|
/* tail the files */
|
||||||
|
|
||||||
fmt = header_fmt + 1; /* Skip header leading newline on first output. */
|
fmt = header_fmt + 1; /* Skip header leading newline on first output. */
|
||||||
i = 0;
|
i = 0;
|
||||||
do {
|
do {
|
||||||
/* Be careful. It would be possible to optimize the count-bytes
|
off_t current;
|
||||||
* case if the file is seekable. If you do though, remember that
|
|
||||||
* starting file position may not be the beginning of the file.
|
|
||||||
* Beware of backing up too far. See example in wc.c.
|
|
||||||
*/
|
|
||||||
if (!(count | from_top) && lseek(fds[i], 0, SEEK_END) >= 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nfiles > header_threshhold) {
|
if (nfiles > header_threshhold) {
|
||||||
tail_xprint_header(fmt, argv[i]);
|
tail_xprint_header(fmt, argv[i]);
|
||||||
fmt = header_fmt;
|
fmt = header_fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Optimizing count-bytes case if the file is seekable.
|
||||||
|
* Beware of backing up too far.
|
||||||
|
* Also we exclude files with size 0 (because of /proc/xxx) */
|
||||||
|
current = lseek(fds[i], 0, SEEK_END);
|
||||||
|
if (current > 0) {
|
||||||
|
if (!from_top) {
|
||||||
|
if (count == 0)
|
||||||
|
continue; /* showing zero lines is easy :) */
|
||||||
|
if (COUNT_BYTES) {
|
||||||
|
current -= count;
|
||||||
|
if (current < 0)
|
||||||
|
current = 0;
|
||||||
|
xlseek(fds[i], current, SEEK_SET);
|
||||||
|
bb_copyfd_size(fds[i], STDOUT_FILENO, count);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buf = tailbuf;
|
buf = tailbuf;
|
||||||
taillen = 0;
|
taillen = 0;
|
||||||
seen = 1;
|
seen = 1;
|
||||||
newline = 0;
|
newlines_seen = 0;
|
||||||
|
|
||||||
while ((nread = tail_read(fds[i], buf, tailbufsize-taillen)) > 0) {
|
while ((nread = tail_read(fds[i], buf, tailbufsize-taillen)) > 0) {
|
||||||
if (from_top) {
|
if (from_top) {
|
||||||
nwrite = nread;
|
nwrite = nread;
|
||||||
@ -215,34 +225,32 @@ int tail_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int k = nread;
|
int k = nread;
|
||||||
int nbuf = 0;
|
int newlines_in_buf = 0;
|
||||||
|
|
||||||
while (k) {
|
do { /* count '\n' in last read */
|
||||||
--k;
|
k--;
|
||||||
if (buf[k] == '\n') {
|
if (buf[k] == '\n') {
|
||||||
++nbuf;
|
newlines_in_buf++;
|
||||||
}
|
}
|
||||||
}
|
} while (k);
|
||||||
|
|
||||||
if (newline + nbuf < count) {
|
if (newlines_seen + newlines_in_buf < count) {
|
||||||
newline += nbuf;
|
newlines_seen += newlines_in_buf;
|
||||||
taillen += nread;
|
taillen += nread;
|
||||||
} else {
|
} else {
|
||||||
int extra = 0;
|
int extra = (buf[nread-1] != '\n');
|
||||||
|
|
||||||
if (buf[nread-1] != '\n')
|
k = newlines_seen + newlines_in_buf + extra - count;
|
||||||
extra = 1;
|
|
||||||
k = newline + nbuf + extra - count;
|
|
||||||
s = tailbuf;
|
s = tailbuf;
|
||||||
while (k) {
|
while (k) {
|
||||||
if (*s == '\n') {
|
if (*s == '\n') {
|
||||||
--k;
|
k--;
|
||||||
}
|
}
|
||||||
++s;
|
s++;
|
||||||
}
|
}
|
||||||
taillen += nread - (s - tailbuf);
|
taillen += nread - (s - tailbuf);
|
||||||
memmove(tailbuf, s, taillen);
|
memmove(tailbuf, s, taillen);
|
||||||
newline = count - extra;
|
newlines_seen = count - extra;
|
||||||
}
|
}
|
||||||
if (tailbufsize < taillen + BUFSIZ) {
|
if (tailbufsize < taillen + BUFSIZ) {
|
||||||
tailbufsize = taillen + BUFSIZ;
|
tailbufsize = taillen + BUFSIZ;
|
||||||
@ -251,13 +259,10 @@ int tail_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
buf = tailbuf + taillen;
|
buf = tailbuf + taillen;
|
||||||
}
|
}
|
||||||
}
|
} /* while (tail_read() > 0) */
|
||||||
|
|
||||||
if (!from_top) {
|
if (!from_top) {
|
||||||
xwrite(STDOUT_FILENO, tailbuf, taillen);
|
xwrite(STDOUT_FILENO, tailbuf, taillen);
|
||||||
}
|
}
|
||||||
|
|
||||||
taillen = 0;
|
|
||||||
} while (++i < nfiles);
|
} while (++i < nfiles);
|
||||||
|
|
||||||
buf = xrealloc(tailbuf, BUFSIZ);
|
buf = xrealloc(tailbuf, BUFSIZ);
|
||||||
|
@ -73,7 +73,7 @@ int wc_main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
const char *s, *arg;
|
const char *s, *arg;
|
||||||
const char *start_fmt = "%9"COUNT_FMT;
|
const char *start_fmt = " %9"COUNT_FMT + 1;
|
||||||
const char *fname_fmt = " %s\n";
|
const char *fname_fmt = " %s\n";
|
||||||
COUNT_T *pcounts;
|
COUNT_T *pcounts;
|
||||||
COUNT_T counts[4];
|
COUNT_T counts[4];
|
||||||
|
Loading…
Reference in New Issue
Block a user