Next: Simple Directory Lister, Previous: Opening a Directory, Up: Accessing Directories
This section describes how to read directory entries from a directory stream, and how to close the stream when you are done with it. All the symbols are declared in the header file dirent.h.
This function reads the next entry from the directory. It normally returns a pointer to a structure containing information about the file. This structure is statically allocated and can be rewritten by a subsequent call.
Portability Note: On some systems
readdir
may not return entries for . and .., even though these are always valid file names in any directory. See File Name Resolution.If there are no more entries in the directory or an error is detected,
readdir
returns a null pointer. The followingerrno
error conditions are defined for this function:
EBADF
- The dirstream argument is not valid.
readdir
is not thread safe. Multiple threads usingreaddir
on the same dirstream may overwrite the return value. Usereaddir_r
when this is critical.
This function is the reentrant version of
readdir
. Likereaddir
it returns the next entry from the directory. But to prevent conflicts between simultaneously running threads the result is not stored in statically allocated memory. Instead the argument entry points to a place to store the result.The return value is
0
in case the next entry was read successfully. In this case a pointer to the result is returned in *result. It is not required that *result is the same as entry. If something goes wrong while executingreaddir_r
the function returns a value indicating the error (as described forreaddir
).If there are no more directory entries,
readdir_r
's return value is0
, and *result is set toNULL
.Portability Note: On some systems
readdir_r
may not return a NUL terminated string for the file name, even when there is nod_reclen
field instruct dirent
and the file name is the maximum allowed size. Modern systems all have thed_reclen
field, and on old systems multi-threading is not critical. In any case there is no such problem with thereaddir
function, so that even on systems without thed_reclen
member one could use multiple threads by using external locking.It is also important to look at the definition of the
struct dirent
type. Simply passing a pointer to an object of this type for the second parameter ofreaddir_r
might not be enough. Some systems don't define thed_name
element sufficiently long. In this case the user has to provide additional space. There must be room for at leastNAME_MAX + 1
characters in thed_name
array. Code to callreaddir_r
could look like this:union { struct dirent d; char b[offsetof (struct dirent, d_name) + NAME_MAX + 1]; } u; if (readdir_r (dir, &u.d, &res) == 0) ...
To support large filesystems on 32-bit machines there are LFS variants of the last two functions.
The
readdir64
function is just like thereaddir
function except that it returns a pointer to a record of typestruct dirent64
. Some of the members of this data type (notablyd_ino
) might have a different size to allow large filesystems.In all other aspects this function is equivalent to
readdir
.
The
readdir64_r
function is equivalent to thereaddir_r
function except that it takes parameters of base typestruct dirent64
instead ofstruct dirent
in the second and third position. The same precautions mentioned in the documentation ofreaddir_r
also apply here.