[net.bugs.4bsd] bug in 4.2

smk@axiom.UUCP (Steven M. Kramer) (03/08/84)

	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@mitre-bedford					(MIL)