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?