🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Steven M. Kramer Wed, 07 Mar 1984 21:11
bug in 4.2 (compatibility and actual) readdir/telldir
#186
Author: Steven M. Kramer
Date: Wed, 07 Mar 1984 21:11
41 lines
2557 bytes
	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)
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads