diff options
Diffstat (limited to 'lib/libc/gen/telldir.c')
-rw-r--r-- | lib/libc/gen/telldir.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/libc/gen/telldir.c b/lib/libc/gen/telldir.c index d72b500..54cab5b 100644 --- a/lib/libc/gen/telldir.c +++ b/lib/libc/gen/telldir.c @@ -101,9 +101,21 @@ _seekdir(dirp, loc) return; if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek) return; + /* If it's within the same chunk of data, don't bother reloading */ + if (lp->loc_seek == dirp->dd_seek) { + /* + * If we go back to 0 don't make the next readdir + * trigger a call to getdirentries() + */ + if (lp->loc_loc == 0) + dirp->dd_flags |= __DTF_SKIPREAD; + dirp->dd_loc = lp->loc_loc; + return; + } (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET); dirp->dd_seek = lp->loc_seek; dirp->dd_loc = 0; + dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid */ while (dirp->dd_loc < lp->loc_loc) { dp = _readdir_unlocked(dirp, 0); if (dp == NULL) @@ -112,6 +124,27 @@ _seekdir(dirp, loc) } /* + * when we do a read and cross a boundary, any telldir we + * just did will have wrong information in it. + * We need to move it from "beyond the end of the previous chunk" + * to "the beginning of the new chunk" + */ +void +_fixtelldir(DIR *dirp, long oldseek, long oldloc) +{ + struct ddloc *lp; + + lp = LIST_FIRST(&dirp->dd_td->td_locq); + if (lp != NULL) { + if (lp->loc_loc == oldloc && + lp->loc_seek == oldseek) { + lp->loc_seek = dirp->dd_seek; + lp->loc_loc = dirp->dd_loc; + } + } +} + +/* * Reclaim memory for telldir cookies which weren't used. */ void |