mirror of https://github.com/mkerrisk/man-pages
readdir.3: Explain why readdir_r() is deprecated and readdir() is preferred
Based on Florian Weimer's text that was added to the glibc manual; relicensed for use in this man page by permission of Florian. See http://www.austingroupbugs.net/view.php?id=696 and https://sourceware.org/bugzilla/show_bug.cgi?id=14699 Cowritten-by: Florian Weimer <fweimer@redhat.com> Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
parent
cff459dea2
commit
0c52f6d623
|
@ -1,5 +1,6 @@
|
|||
.\" Copyright (C) 1993 David Metcalfe (david@prism.demon.co.uk)
|
||||
.\" and Copyright (C) 2008 Michael Kerrisk <mtk.manpages@gmail.com>
|
||||
.\" and Copyright (C) 2008, 2016 Michael Kerrisk <mtk.manpages@gmail.com>
|
||||
.\" and Copyright (C) 2016 Florian Weimer <fweimer@redhat.com>
|
||||
.\"
|
||||
.\" %%%LICENSE_START(VERBATIM)
|
||||
.\" Permission is granted to make and distribute verbatim copies of this
|
||||
|
@ -124,7 +125,7 @@ field, and other nonstandard fields may precede that field within the
|
|||
.I dirent
|
||||
structure, portable applications that use
|
||||
.BR readdir_r ()
|
||||
should allocate the buffer whose address is passed in
|
||||
could allocate the buffer whose address is passed in
|
||||
.IR entry
|
||||
as follows:
|
||||
.in +4n
|
||||
|
@ -142,6 +143,61 @@ entryp = malloc(len);
|
|||
.I d_name
|
||||
is the last field in a
|
||||
.IR "struct dirent" .)
|
||||
|
||||
However, the above approach has problems,
|
||||
and it is recommended that applications use
|
||||
.BR readdir ()
|
||||
instead of
|
||||
.BR readdir_r ().
|
||||
Furthermore, since version 2.24, glibc deprecates
|
||||
.BR readdir_r ().
|
||||
The reasons are as follows:
|
||||
.IP * 3
|
||||
On systems where
|
||||
.BR NAME_MAX
|
||||
is undefined, calling
|
||||
.BR readdir_r ()
|
||||
may be unsafe because the interface does not allow the caller to specify
|
||||
the length of the buffer used for the returned directory entry.
|
||||
.IP *
|
||||
On some systems,
|
||||
.BR readdir_r ()
|
||||
can't read directory entries with very long names.
|
||||
When the glibc implementation encounters such a name,
|
||||
.BR readdir_r ()
|
||||
fails with the error
|
||||
.B ENAMETOOLONG
|
||||
.IR "after the final directory entry has been read" .
|
||||
On some other systems,
|
||||
.BR readdir_r ()
|
||||
may return a success status, but the returned
|
||||
.IR d_name
|
||||
field may not be null terminated or may be truncated.
|
||||
.IP *
|
||||
In the current POSIX.1 specification (POSIX.1-2008),
|
||||
.BR readdir ()
|
||||
is not required to be thread-safe.
|
||||
However, in modern implementations (including the glibc implementation),
|
||||
concurrent calls to
|
||||
.BR readdir ()
|
||||
that specify different directory streams are thread-safe.
|
||||
Therefore, the use of
|
||||
.BR readdir_r ()
|
||||
is generally unnecessary in multithreaded programs.
|
||||
In cases where multiple threads must read from the same directory stream,
|
||||
using
|
||||
.BR readdir ()
|
||||
with external synchronization is still preferable to the use of
|
||||
.BR readdir_r (),
|
||||
for the reasons given in the points above.
|
||||
.IP *
|
||||
It is expected that a future version of POSIX.1
|
||||
.\" http://www.austingroupbugs.net/view.php?id=696
|
||||
will make
|
||||
.BR readdir_r ()
|
||||
obsolete, and require that
|
||||
.BR readdir ()
|
||||
be thread-safe when concurrently employed on different directory streams.
|
||||
.SH RETURN VALUE
|
||||
On success,
|
||||
.BR readdir ()
|
||||
|
@ -170,6 +226,9 @@ returns 0, and returns NULL in
|
|||
.TP
|
||||
.B EBADF
|
||||
Invalid directory stream descriptor \fIdirp\fP.
|
||||
.TP
|
||||
.B ENAMETOOLOMG
|
||||
A directory entry whose name was too long to be read was encountered.
|
||||
.SH ATTRIBUTES
|
||||
For an explanation of the terms used in this section, see
|
||||
.BR attributes (7).
|
||||
|
|
Loading…
Reference in New Issue