manual: readdir, readdir64 are thread-safe

They only modify the state in the dirstream argument, and we
generally do not treat this as a reason to mark a function as
not thread-safe.  For an example, see random_r, which is marked
as thread-safe even though the random state is not protected
by a lock.
This commit is contained in:
Florian Weimer 2017-04-11 18:04:34 +02:00
parent 38efe8c5a5
commit a42478b7bf
2 changed files with 26 additions and 9 deletions

View File

@ -1,3 +1,9 @@
2017-04-11 Florian Weimer <fweimer@redhat.com>
Zack Weinberg <zackw@panix.com>
* manual/filesys.texi (Reading/Closing Directory): Mark readdir,
readdir64 as thread-safe. Update warning about readdir_r.
2017-04-10 Adhemerval Zanella <adhemerval.zanella@linaro.org> 2017-04-10 Adhemerval Zanella <adhemerval.zanella@linaro.org>
* sysdeps/unix/sysv/linux/x86/Implies: New file. * sysdeps/unix/sysv/linux/x86/Implies: New file.

View File

@ -478,7 +478,7 @@ symbols are declared in the header file @file{dirent.h}.
@comment dirent.h @comment dirent.h
@comment POSIX.1 @comment POSIX.1
@deftypefun {struct dirent *} readdir (DIR *@var{dirstream}) @deftypefun {struct dirent *} readdir (DIR *@var{dirstream})
@safety{@prelim{}@mtunsafe{@mtasurace{:dirstream}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
@c This function holds dirstream's non-recursive lock, which brings @c This function holds dirstream's non-recursive lock, which brings
@c about the usual issues with locks and async signals and cancellation, @c about the usual issues with locks and async signals and cancellation,
@c but the lock taking is not enough to make the returned value safe to @c but the lock taking is not enough to make the returned value safe to
@ -507,13 +507,24 @@ must set @code{errno} to zero before calling @code{readdir}. To avoid
entering an infinite loop, you should stop reading from the directory entering an infinite loop, you should stop reading from the directory
after the first error. after the first error.
In POSIX.1-2008, @code{readdir} is not thread-safe. In @theglibc{} @strong{Caution:} The pointer returned by @code{readdir} points to
implementation, it is safe to call @code{readdir} concurrently on a buffer within the @code{DIR} object. The data in that buffer will
different @var{dirstream}s, but multiple threads accessing the same be overwritten by the next call to @code{readdir}. You must take care,
@var{dirstream} result in undefined behavior. @code{readdir_r} is a for instance, to copy the @code{d_name} string if you need it later.
fully thread-safe alternative, but suffers from poor portability (see
below). It is recommended that you use @code{readdir}, with external Because of this, it is not safe to share a @code{DIR} object among
locking if multiple threads access the same @var{dirstream}. multiple threads, unless you use your own locking to ensure that
no thread calls @code{readdir} while another thread is still using the
data from the previous call. In @theglibc{}, it is safe to call
@code{readdir} from multiple threads as long as each thread uses
its own @code{DIR} object. POSIX.1-2008 does not require this to
be safe, but we are not aware of any operating systems where it
does not work.
@code{readdir_r} allows you to provide your own buffer for the
@code{struct dirent}, but it is less portable than @code{readdir}, and
has problems with very long filenames (see below). We recommend
you use @code{readdir}, but do not share @code{DIR} objects.
@end deftypefun @end deftypefun
@comment dirent.h @comment dirent.h
@ -592,7 +603,7 @@ of the last two functions.
@comment dirent.h @comment dirent.h
@comment LFS @comment LFS
@deftypefun {struct dirent64 *} readdir64 (DIR *@var{dirstream}) @deftypefun {struct dirent64 *} readdir64 (DIR *@var{dirstream})
@safety{@prelim{}@mtunsafe{@mtasurace{:dirstream}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
The @code{readdir64} function is just like the @code{readdir} function The @code{readdir64} function is just like the @code{readdir} function
except that it returns a pointer to a record of type @code{struct except that it returns a pointer to a record of type @code{struct
dirent64}. Some of the members of this data type (notably @code{d_ino}) dirent64}. Some of the members of this data type (notably @code{d_ino})