bug in 4.2 (compatibility and actual) readdir/telldir
Steven M. Kramer
smk at axiom.UUCP
Thu Mar 8 07:11:38 AEST 1984
When a readdir() is done, if the read fails, dd_size becomes -1
and readdir() returns NULL. If a telldir() is then done, the location
is off by one. That's because readdir() should reset dd_size to 0 (which
is what it was BEFORE it entered the if test in readdir() ). The fix is to
reset dd_size to 0, which is what it was before the read() was done.
There may be other similar problems along this vein,
but offhand I can't think of any.
As for my past bug fix (for those of you that still have that version
of the 4.2 compatibility library), I fixed one bug but put another back in.
Mark Plotnick found the problem and fixed if by reading the test for dd_loc!=0
in seekdir(). The problem, according to Mark, was:
In your original code, if offset is 0, then the lseek is done, but
readdir isn't called at all. (the test at the top of the while loop
fails). Therefore, dd_size and dd_buf still contain info pertaining to
the old block. As soon as a readdir is done everything will be OK,
since the new block will be read in; the problem only occurs if a
seekdir is done without an intervening readdir. If the seekdir is to
a spot within the current block (not at the beginning), then your
test succeeds (since you're only checking offset), dd_loc is set to
the (non-zero) offset, and bingo we've clobbered the only signal we have
that the new block needed to be read in. Admittedly this will
probably never happen; I can't even think of a use for telldir() and
seekdir() other than to rewind the directory to the beginning.
The fix is to change:
if (offset != 0 && (curloc & ~(DIRBLKSIZ-1)) == base) {
--to--
if (dirp->dd_loc != 0 && offset != 0 && (curloc & ~(DIRBLKSIZ-1)) == base) {
Both the offset and dd_loc check are needed.
Mark also correctly states that
dirp->dd_size = 0;
should be added after the
dirp->dd_loc = 0;
line in seekdir().
--
--steve kramer
{allegra,genrad,ihnp4,utzoo,philabs,uw-beaver}!linus!axiom!smk (UUCP)
linus!axiom!smk at mitre-bedford (MIL)
More information about the Net.bugs
mailing list