[PATCH] Fix readdir_r with long file names
Michael Kerrisk (man-pages)
mtk.manpages@gmail.com
Wed Mar 2 10:39:00 GMT 2016
On 03/02/2016 12:44 AM, Florian Weimer wrote:
> On 03/02/2016 12:25 AM, Paul Eggert wrote:
>
>>> And at the cost of
>>> changing sizeof (struct dirent), which can't be a good thing.
>>
>> Any program that depends on sizeof (struct dirent) is broken already, so
>> this isn't that worrisome.
>
> Just to be clear, you looked at the wrong struct dirent definition for
> GNU/Linux, there is a sysdeps override.
>
> Right now, most programs relying on sizeof (struct dirent) work well in
> almost all cases. We really don't want to break that. There appears to
> be an overlap between these programs and users of readdir_r, so once we
> remove that from the API, we should have better story for struct dirent
> declarators as well.
So, it seems like much more could be said about this in documentation.
How about the following text for the man page?
DESCRIPTION
[...]
In the glibc implementation, the dirent structure is defined as
follows:
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported
by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
[...]
NOTES
The d_name field
The dirent structure definition shown above is taken from the
glibc headers, and shows the d_name field with a fixed size.
Warning: applications should avoid any dependence on the size
of the dname field. POSIX defines it as char d_name[], a charâ
acter array of unspecified size, with at most NAME_MAX characâ
ters preceding the terminating null byte ('\0').
POSIX.1 explicitly notes that this field should not be used as
an lvalue. The standard also notes that the use of
sizeof(d_name) (and by implication sizeof(struct dirent)) is
incorrect; use strlen(d_name) instead. (On some systems, this
field is defined as char d_name[1]!)
Note that while the call
fpathconf(fd, _PC_NAME_MAX)
returns the value 255 for most filesystems, on some filesystems
(e.g., CIFS, Windows SMB servers), the null-terminated filename
that is (correctly) returned in d_name can actually exceed this
size. (In such cases, the d_reclen field will contain a value
that exceeds the size of the glibc dirent structure shown
above.)
Cheers,
Michael
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
More information about the Libc-alpha
mailing list