From owner-freebsd-hackers Thu Nov 30 02:16:50 1995 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id CAA14484 for hackers-outgoing; Thu, 30 Nov 1995 02:16:50 -0800 Received: from ref.tfs.com (ref.tfs.com [140.145.254.251]) by freefall.freebsd.org (8.6.12/8.6.6) with ESMTP id CAA14469 for ; Thu, 30 Nov 1995 02:16:46 -0800 Received: (from julian@localhost) by ref.tfs.com (8.6.12/8.6.9) id CAA11729 for hackers@freebsd.org; Thu, 30 Nov 1995 02:16:25 -0800 Date: Thu, 30 Nov 1995 02:16:25 -0800 From: Julian Elischer Message-Id: <199511301016.CAA11729@ref.tfs.com> To: hackers@freebsd.org Subject: broken readdir? Sender: owner-hackers@freebsd.org Precedence: bulk we seem to have broken readdir in libc.. the man page says: The readdir() function returns a pointer to the next directory entry. It returns NULL upon reaching the end of the directory or detecting an in- valid seekdir() operation. but the following code in WINE breaks, and I can see it breaking in gdb.. 03 struct dosdirent *DOS_readdir(struct dosdirent *de) 904 { 905 char temp[WINE_PATH_LENGTH]; (gdb) 906 struct dirent *d; 907 struct stat st; 908 DIR *ds; 909 910 if (!de->inuse) 911 return NULL; 912 if (!(ds=opendir(de->unixpath))) return NULL; 913 seekdir(ds,de->telldirnum); /* returns no error value. strange */ [..] code skipped over.. 929 do { 930 if ((d = readdir(ds)) == NULL) { 931 de->telldirnum=telldir(ds); 932 closedir(ds); 933 return NULL; 934 } 935 (gdb) 936 de->entnum++; /* Increment the directory entry number */ 937 strcpy(de->filename, d->d_name); 938 if (d->d_reclen > 12) 939 de->filename[12] = '\0'; 940 941 ToDos(de->filename); 942 } while ( !match(de->filename, de->filemask) ); (gdb) print de->telldirnum $3 = 16432 (gdb) print *ds $4 = {dd_fd = 12, dd_loc = 12, dd_size = 1536, dd_buf = 0x21c000 "p@", dd_len = 4096, dd_seek = 0, dd_rewind = 16433} the directory is 1536 bytes long, so a seek to 16k SHOULD result in the next readdir() returning NULL, no? however the readdir on line 931 DOES NOT return null, but rather returns the ADDRESS OF THE FIRST ENTRY '.' Wine is looping forever, as it doesn't realise it's reached the end of the dir, and looks at '.', '.', '.', '.' (stat, stat, stat etc) the code in wine LOOKS RIGHT to me, but BY GUM the code in readdir/seekdir is horrid. if anyone can see a bug in either the WINE code or seekdir/readdir I'd really be obliged... (I'm SURE the bug is in readdir..) julian +----------------------------------+ ______ _ __ | __--_|\ Julian Elischer | \ U \/ / On assignment | / \ julian@ref.tfs.com +------>x USA \ in a very strange | ( OZ ) 300 lakeside Dr. oakland CA. \___ ___ | country ! +- X_.---._/ USA+(510) 645-3137(wk) \_/ \\ v