Path: utzoo!attcan!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;