diff options
author | Michael Stapelberg <stapelberg@google.com> | 2020-02-07 08:41:26 +0100 |
---|---|---|
committer | Oliver Kiddle <opk@zsh.org> | 2021-04-11 21:38:27 +0200 |
commit | 638815623368683e685a8d706e57634f6fec6401 (patch) | |
tree | 280132f53ffe4f09e0bf84891fd32b170b4f9890 /Src | |
parent | 82ba2261abbfa5673fbd5df980c8cbbeb7946653 (diff) | |
download | zsh-638815623368683e685a8d706e57634f6fec6401.tar.gz zsh-638815623368683e685a8d706e57634f6fec6401.tar.xz zsh-638815623368683e685a8d706e57634f6fec6401.zip |
45396: readhistfile: avoid thousands of lseek(2) syscalls via ftell()
Diffstat (limited to 'Src')
-rw-r--r-- | Src/hist.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/Src/hist.c b/Src/hist.c index 8ab7828e8..2e5ac97d9 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -2589,11 +2589,13 @@ resizehistents(void) } static int -readhistline(int start, char **bufp, int *bufsiz, FILE *in) +readhistline(int start, char **bufp, int *bufsiz, FILE *in, int *readbytes) { char *buf = *bufp; if (fgets(buf + start, *bufsiz - start, in)) { - int len = start + strlen(buf + start); + int len = strlen(buf + start); + *readbytes += len; + len += start; if (len == start) return -1; if (buf[len - 1] != '\n') { @@ -2602,7 +2604,7 @@ readhistline(int start, char **bufp, int *bufsiz, FILE *in) return -1; *bufp = zrealloc(buf, 2 * (*bufsiz)); *bufsiz = 2 * (*bufsiz); - return readhistline(len, bufp, bufsiz, in); + return readhistline(len, bufp, bufsiz, in, readbytes); } } else { @@ -2610,7 +2612,7 @@ readhistline(int start, char **bufp, int *bufsiz, FILE *in) if (len > 1 && buf[len - 2] == '\\') { buf[--len - 1] = '\n'; if (!feof(in)) - return readhistline(len, bufp, bufsiz, in); + return readhistline(len, bufp, bufsiz, in, readbytes); } } return len; @@ -2630,7 +2632,7 @@ readhistfile(char *fn, int err, int readflags) short *words; struct stat sb; int nwordpos, nwords, bufsiz; - int searching, newflags, l, ret, uselex; + int searching, newflags, l, ret, uselex, readbytes; if (!fn && !(fn = getsparam("HISTFILE"))) return; @@ -2672,13 +2674,15 @@ readhistfile(char *fn, int err, int readflags) } else searching = 0; + fpos = ftell(in); + readbytes = 0; newflags = HIST_OLD | HIST_READ; if (readflags & HFILE_FAST) newflags |= HIST_FOREIGN; if (readflags & HFILE_SKIPOLD || (hist_ignore_all_dups && newflags & hist_skip_flags)) newflags |= HIST_MAKEUNIQUE; - while (fpos = ftell(in), (l = readhistline(0, &buf, &bufsiz, in))) { + while (fpos += readbytes, readbytes = 0, (l = readhistline(0, &buf, &bufsiz, in, &readbytes))) { char *pt; int remeta = 0; |