On Sat, Mar 25, 2017 at 12:53 PM, Florian Weimer <[email protected]> wrote:
> * Yann Ylavic:
>
>> On Fri, Mar 24, 2017 at 7:35 PM, William A Rowe Jr
>> <[email protected]> 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?