From Bugzilla Helper: User-Agent: Mozilla/4.78 [en] (X11; U; Linux 2.4.17 i686) Description of problem: The described structure and prototype do not match the kernel, the include list is incorrect, the 64bit call and structure are not documented, and the comment for the offset field is incorrect. Also, the array length is incorrect (the page should probably mention that this field is actually dynamic), the fact that the offset is only a cookie is not mentioned. Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: 1. read manpage 2. try to use the information 3. end up reading kernel source and searching google for better info Actual Results: See below. Expected Results: See below. Additional info: Bug 1: getdents(2) should describe the kernel system call interface. The types do not match the kernel version in signedness. /* from Linux 2.4.18 */ struct linux_dirent { unsigned long d_ino; /* inode number */ unsigned long d_off; /* offset from the start of the directory */ unsigned short d_reclen; /* length of this record */ char d_name[1]; /* filename with null-termination, length is variable */ }; Bug 2: The d_off field is misdocumented as being the offset to the next directory entry in the current manpage. Bug 3: The name field is misdocumented as being limited to NAME_MAX+1 chars in the current manpage. That bug has a sub-bug which is that there should be no +1 since NAME_MAX should already include room for the NUL termination. Bug 4: The return type should be "long" instead of "int". The syscall prototype from 2.4.18: long sys_getdents(unsigned int fd, void * dirent, unsigned int count); (You can substitute "struct dirent" in place of "void".) Bug 5: getdents64() is not documented nor is the structure. struct linux_dirent64 { __u64 d_ino; /* inode number */ __s64 d_off; /* offset from start of directory */ unsigned short d_reclen; /* length of this record */ unsigned char d_type; /* hint for type of inode (file,directory,etc.) */ char d_name[0]; /* filename including null-termination, variable length */ } Bug 6: The manpage should describe how to use the function. The first thing to note is that one needs to allocate more space than given by struct dirent so that the kernel can fill in the file name. The second thing to note is that the return value does not give enough information to tell how many structures have been read without counting the d_reclen fields. It should also mention that the C library may have its own version of struct dirent which may conflict with the kernel version. The third thing to note is that the d_off field should not be treated as an offset in bytes (though it usually is) but as a cookie. This means doing to math on it. It may only be fed to lseek(64) as-is. This is especially important on non-POSIX filesystems like NFS. Bug 7: The list of includes is not correct. Including unistd.h may conflict with kernel headers (mixing glibc and kernel headers is usually a bad idea). The man page should probably warn against including unistd.h or sys/types.h from the C library since they also define a different struct dirent. The only headers which need to be included are: #include <linux/unistd.h> #include <linux/types.h> There is a linux/dirent.h header with what seem to be kernel structures, but they limit filenames to 256 characters. However, neither of those will define the kernel getdents structure. The manpage should make it clear that you will need to define it yourself. Summary: This man page has several factual problems and several omissions. If you would rather I report this bug directly to the LDP then I would be glad to do so. Please CC me on any updates or information requests.
The best place to submit this is the man-page author, aeb