Lots of programs still use readdir instead of readdir64. But I got a case where they return different results. The following runs on my machine running linux-2.4.2 on with glibc-2.2.2 (x86) The relevant directory is NFS mounted from a SGI server (nfs2) ----------------------- junk.c #include #include int main(int argc, char **argv) { struct DIRENT *ent = 0; DIR *dir = opendir(argv[1]); while ((ent = READDIR(dir))) puts(ent->d_name); closedir(dir); } -------------------------- Let's compare the 32 and 64 bit versions: % gcc -D_GNU_SOURCE -DDIRENT=dirent -DREADDIR=readdir -o junk32 junk.c % junk32 mimelnk/ . .. audio video application % gcc -D_GNU_SOURCE -DDIRENT=dirent64 -DREADDIR=readdir64 -o junk64 junk.c % junk64 mimelnk/ . .. audio video application image <--------- This file was missing! ---------------------------- In glibc-2.2.2, both readdir and readdir64 use syscall __NR_getdents64. Here is a capture of what __NR_getdents64 returns: 0x62, 0xce, 0xbe, 0x02, 0x00, 0x00, 0x00, 0x00, // d_ino 0x2e, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // d_off 0x18, 0x00, 0x00, /* . */ // d_reclen d_type 0x2e, 0x00, 0x00, 0x00, 0x00, // d_name 0xe0, 0x05, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x34, 0xb9, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, /* .. */ 0x2e, 0x2e, 0x00, 0x00, 0x00, 0x1d, 0xd0, 0x69, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x32, 0x39, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, /* audio */ 0x61, 0x75, 0x64, 0x69, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcf, 0x69, 0x03, 0x00, 0x00, 0x00, 0x00, 0x88, 0xc8, 0x43, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, /* video */ 0x76, 0x69, 0x64, 0x65, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x62, 0xe5, 0x02, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x73, 0xb8, 0x9d, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, /* application */ 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0xa8, 0xa1, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, // last d_ino 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // last d_off 0x20, 0x00, 0x00, /* image */ 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 Note the strange numbers in the d_off fields. These are in fact cookies used internally by nfs. Under nfs2, these are 32 bit unsigned number. The linux kernel (2.4.2) sign extend these to 64 bits except for the last one wich is filled separately by the vfs and is not sign extended. The glibc-2.2.2 source code for readdir() eventually arrives in function getdents and notices that the last d_off cannot fit into a signed 32 bit number. This behavior is commented : << Overflow. If there was at least one entry before this one, return them without error, otherwise signal overflow. >> Note that this could be considered a linux problem. NFS2 should properly sign extend the last d_off. I patched my linux kernel, posted a message (no reply). On the other hand, NFS3 already uses 64 bit cookies and newer disk file systems use 64 bits inodes. Most applications using readdir() just care about the filenames and do not even access the d_ino and d_off fields. These applications should be allowed to work with newer file systems as well. Otherwise we would have a show stopper there. Instead of returning EOVERFLOW or simply bailing out with the filenames returned so far, wouldn't it be better to set these fields to some error value such as -1 ? Thanks for the good work. - Leon Bottou _______________________________________________ Bug-glibc mailing list Bug-glibc@gnu.org http://mail.gnu.org/mailman/listinfo/bug-glibc