Reading and Closing a Directory Stream
--------------------------------------
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'.
- Function: struct dirent * readdir (DIR *DIRSTREAM)
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. Note:File Name Resolution.
If there are no more entries in the directory or an error is
detected, `readdir' returns a null pointer. The following `errno'
error conditions are defined for this function:
`EBADF'
The DIRSTREAM argument is not valid.
`readdir' is not thread safe. Multiple threads using `readdir' on
the same DIRSTREAM may overwrite the return value. Use
`readdir_r' when this is critical.
- Function: int readdir_r (DIR *DIRSTREAM, struct dirent *ENTRY,
struct dirent **RESULT)
This function is the reentrant version of `readdir'. Like
`readdir' 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 executing `readdir_r' the function
returns a value indicating the error (as described for `readdir').
If there are no more directory entries, `readdir_r''s return value
is `0', and *RESULT is set to `NULL'.
*Portability Note:* On some systems `readdir_r' may not return a
NUL terminated string for the file name, even when there is no
`d_reclen' field in `struct dirent' and the file name is the
maximum allowed size. Modern systems all have the `d_reclen'
field, and on old systems multi-threading is not critical. In any
case there is no such problem with the `readdir' function, so that
even on systems without the `d_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 of `readdir_r' might not be enough. Some
systems don't define the `d_name' element sufficiently long. In
this case the user has to provide additional space. There must be
room for at least `NAME_MAX + 1' characters in the `d_name' array.
Code to call `readdir_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.
- Function: struct dirent64 * readdir64 (DIR *DIRSTREAM)
The `readdir64' function is just like the `readdir' function
except that it returns a pointer to a record of type `struct
dirent64'. Some of the members of this data type (notably `d_ino')
might have a different size to allow large filesystems.
In all other aspects this function is equivalent to `readdir'.
- Function: int readdir64_r (DIR *DIRSTREAM, struct dirent64 *ENTRY,
struct dirent64 **RESULT)
The `readdir64_r' function is equivalent to the `readdir_r'
function except that it takes parameters of base type `struct
dirent64' instead of `struct dirent' in the second and third
position. The same precautions mentioned in the documentation of
`readdir_r' also apply here.
- Function: int closedir (DIR *DIRSTREAM)
This function closes the directory stream DIRSTREAM. It returns
`0' on success and `-1' on failure.
The following `errno' error conditions are defined for this
function:
`EBADF'
The DIRSTREAM argument is not valid.