Reputation: 6596
Context:
The readdir_r
function is used to read the next entry from a DIR*
(there's also readdir
, but that's not thread-safe). readdir_r
takes a pointer to a user-allocated buffer to hold the output dirent
. The manpage indicates that the size required for this buffer may be different on different systems, and provides an example of how to find a safe length at runtime:
len = offsetof(struct dirent, d_name) + pathconf(dirpath, _PC_NAME_MAX) + 1;
(warning: there is a race condition in the above, which can be avoided by using dirfd
to get the file descriptor for the opened DIR*
and using fpathconf
instead of pathconf
)
Question:
Looking at the manpage for pathconf
, it states:
_PC_NAME_MAX returns the maximum length of a filename in the directory path or fd that the process is allowed to create. The corresponding macro is _POSIX_NAME_MAX.
However, in the notes section, it states:
Files with name lengths longer than the value returned for name equal to _PC_NAME_MAX may exist in the given directory.
Is this note true? If so, is the example code in the readdir_r
man-page incorrect?
Upvotes: 4
Views: 1441
Reputation: 11252
That interpretation of {NAME_MAX} does not agree with POSIX. POSIX says that implementations must treat names longer than {NAME_MAX} as an error and that a d_name
buffer of {NAME_MAX}+1 bytes is sufficient.
An alternative (POSIX.1-2008) is to use scandir()
which is thread-safe and abstracts this issue from the caller. Unfortunately, there is no scandirat()
or fscandir()
in any version of POSIX.
On many systems, it is also safe to use readdir()
as long as the last access to the returned struct dirent
happens-before the next call to readdir()
(which follows from the existing requirements on the validity of the structure). I think there is little reason for POSIX not to permit this. readdir_r()
requires quite a lot of extra code which makes things slower and more complex.
Upvotes: 3