Bug in 4.1C seekdir() & rewinddir()

Rick Adams ra at rlgvax.UUCP
Thu Oct 6 09:49:56 AEST 1983


If you have a directory with 1 entry in it and you do the following
sequence:

	dirp = opendir("whatever");
	dp = readdir(dirp);
	rewinddir(dirp);
	dp2 = readdir(dirp);

The second readdir will NOT find the file. This is because of an
optimization in seekdir (rewinddir is a macro defined as
seekdir(dirp,0L)) The optimization fails in the special case of a seek
to location 0 while you are in the first block.

The optimization is an attempt to avoid re-reading the directory block
when the block is already in the buffer. Unfortunately, readdir uses a
pointer to location 0 as a flag to read in the next block, so a true
seek must be done.

The following diff shows a fix:

*** seekdir.c.old	Wed Oct  5 19:53:08 1983
--- seekdir.c	Wed Oct  5 19:03:22 1983
***************
*** 22,28
  		return;
  	base = loc & ~(DIRBLKSIZ - 1);
  	offset = loc & (DIRBLKSIZ - 1);
! 	if (dirp->dd_loc != 0 && (curloc & ~(DIRBLKSIZ - 1)) == base) {
  		dirp->dd_loc = offset;
  		return;
  	}

--- 23,29 -----
  		return;
  	base = loc & ~(DIRBLKSIZ - 1);
  	offset = loc & (DIRBLKSIZ - 1);
! 	if (dirp->dd_loc != 0 && offset != 0 && (curloc & ~(DIRBLKSIZ - 1)) == base) {
  		dirp->dd_loc = offset;
  		return;
  	}

Some versions of uucp use rewinddir() to re-read the work directory
instead of closing and re-opening the directory.
This bug will cause entries to be missed unless it is corrected.


Rick Adams
{seismo|ihnp4|allegra|mcnc}!rlgvax!ra



More information about the Comp.bugs.4bsd.ucb-fixes mailing list