Path: tut!sunic!mcsun!uunet!ginosko!gem.mps.ohio-state.edu!tut.cis.ohio-state.edu!ucbvax!hplabs!hpl-opus!hpccc!culberts
From: culberts@hpccc.HP.COM (Bruce Culbertson)
Newsgroups: comp.os.minix
Subject: getdents.c bug fix, fixes new ls also
Message-ID: <6910004@hpccc.HP.COM>
Date: 24 Aug 89 16:35:28 GMT
Organization: Hewlett-Packard Co.
Lines: 74

Bravo for the new ls -- it is a big improvement.  Several people have noticed
that it fails on large directories, though.  The problem is actually in
the library file getdents.c.  The cdiff below seems to fix the problem on
my system.  It should now work for directories of arbitrary size and there
should no longer be any special requirements on the size of the buffer
passed to getdents().  Previously, readdir() passed a buffer which was
too small to work with the original getdents().

A small nit I have with both the new and old ls's: the long format expects
user id's to be at most 6 characters.  My user id (culberts) fouls up the
columns.

Bruce Culbertson
culberts@hplabs.hp.com
--------------------------------  cut here  --------------------------------
*** getdents.old	Thu Aug 24 09:04:24 1989
--- getdents.c	Thu Aug 24 09:09:22 1989
***************
*** 100,107 ****
  #endif
  
  #ifndef DIRBLKSIZ
! #define	DIRBLKSIZ	4096		/* directory file read buffer size */
  #endif
  
  #ifndef NULL
  #define	NULL	0
--- 100,117 ----
  #endif
  
  #ifndef DIRBLKSIZ
! /* directory file read buffer size
!  * For directory files with fixed sized records, this should be a
!  * multiple of the record size.  For variable sized records, this code
!  * is probably unreliable if the directory is larger than DIRBLKSIZ --
!  * so make DIRBLKSIZ big.
!  */
! #ifdef UFS
! #define	DIRBLKSIZ (64*sizeof(struct direct))
! #else
! #define	DIRBLKSIZ 4096
  #endif
+ #endif
  
  #ifndef NULL
  #define	NULL	0
***************
*** 275,282 ****
  
  				if ( (char *)bp + reclen > &buf[nbyte] )
  					{
! 					errno = EINVAL;
! 					return -1;	/* buf too small */
  					}
  
  				bp->d_ino = dp->d_fileno;
--- 285,301 ----
  
  				if ( (char *)bp + reclen > &buf[nbyte] )
  					{
! 					/* buf too small, lseek so we get the
! 					 * rest on next call to getdents() 
! 					 */
! 					if (lseek (fildes,
! 					(long)((char *)dp-u.dblk),
! 					SEEK_CUR) < 0)
! 						{
! 						/* errno set by lseek */
! 						return -1;
! 						}
! 					break;
  					}
  
  				bp->d_ino = dp->d_fileno;
