On Sat, Mar 25, 2017 at 12:53 PM, Florian Weimer <f...@deneb.enyo.de> wrote:
> * Yann Ylavic:
>
>> On Fri, Mar 24, 2017 at 7:35 PM, William A Rowe Jr
>> <wr...@rowe-clan.net> wrote:
>>>
>>> I haven't built 1.x branch against openssl 110 yet,
>>
>> I did with 1.6.x (on latest Debian's libbsl-1.1) with no issue.
>>
>>> so here's some Unix (latest Fedora) feedback;
>>>
>>> ../../apr-1.6/file_io/unix/dir.c: In function ‘apr_dir_read’:
>>> ../../apr-1.6/file_io/unix/dir.c:162:5: warning: ‘readdir_r’ is
>>> deprecated [-Wdeprecated-declarations]
>>>      ret = readdir_r(thedir->dirstruct, thedir->entry, &retent);
>>>      ^~~
>>> In file included from
>>> /home/wrowe/dev/apr-1.6/include/arch/unix/apr_arch_file_io.h:50:0,
>>>                  from ../../apr-1.6/file_io/unix/dir.c:17:
>>> /usr/include/dirent.h:183:12: note: declared here
>>>  extern int readdir_r (DIR *__restrict __dirp,
>>>             ^~~~~~~~~
>>
>> Same here, but this is really a weird situation where readdir_r() is
>> deprecated and "googling" advises are either to use readdir() with a
>> lock (because it's not thread-safe...),
>
> readdir is thread-safe.  There used to be this idea that fdopendir
> could be implemented like this:
>
> DIR *
> fdopendir (int fd)
> {
>   return (DIR *) fd;
> }
>
> And readdir would use a static buffer for the directory entry (like
> gethostbyname) instead of something which is allocated as part of the
> opaque the DIR * object (similar to a FILE *).  Such systems may
> indeed have existed at one point, but I doubt that you can compile APR
> on them.  It's unlikely that these systems will support readdir_r
> because it is much to recent an interface.

Right, modern readdir()s seem to be thread-safe but with regard to
different directories only, at least Linux' man page states:
        "In the current POSIX.1 specification (POSIX.1-2008),
readdir() is not required to be thread-safe.  However, in modern
implementations (including the glibc implementation), concurrent calls
to readdir() that specify different directory streams are thread-safe.
In cases where multiple threads must read from the same directory
stream, using readdir() with external synchronization is still
preferable to the use of the  deprecated readdir_r(3) function.  It is
expected that a future version of POSIX.1 will require that readdir()
be thread-safe when concurrently employed on different directory
streams."

>
> For systems which use a buffer embedded in the DIR * object (and I'm
> not aware of any which don't), readdir is as thread-safe as memcpy,
> although some manual pages claim it is not.  This is very likely an
> editorial mistake because thread safety guarantees for functions which
> operate on separate objects are still an evolving concept.

Are you thinking of the above editorial?

>
>> or to still use readdir_r()
>> but malloc the passed in entry (with an overly complicated/hardly
>> portable thing to compute its size) so to avoid the defect (albeit not
>> the warning!) because of which readdir_r() is deprecated.
>
> It doesn't avoid all defects.  On most systems, computing the correct
> size of the readdir_r buffer is close to impossible (because of races
> which are very difficult to eliminate, or lack of correct name length
> information from the operating system), and readdir_r cannot check
> that the buffer is large enough because it is not passed the
> allocation size.

Agreed, if there were a solution with readdir_r() I guess the libc
would have implemented it...

>
> There is at least one implementation of readdir_r which will return
> ENAMETOOLONG if names are longer than NAME_MAX characters, while
> readdir will return such names, so using readdir_r will result in
> non-listable directories.
>
> Just stop using readdir_r.  I know that many people are invested in
> that interface for various reasons, but sometimes, you just have to
> delete pointless code and get on with it.

I'm not sure we can use readdir() blindy though, what if multiple
threads use it on the same dir?

Reply via email to