On 10/02/2015 06:34 AM, Jonathan Wakely wrote:
On 02/10/15 14:16 +0200, Florian Weimer wrote:
On 09/29/2015 01:37 PM, Jonathan Wakely wrote:
POSIX says that dirent::d_name has an unspecified length, so calls to
readdir_r must pass a buffer with enough trailing space for
{NAME_MAX}+1 characters. I wasn't doing that, which works OK on
GNU/Linux and BSD where d_name is a large array, but fails on Solaris
32-bit.
This uses pathconf to get NAME_MAX and allocates a buffer.
This still has a buffer overflow on certain file systems.
You must not use readdir_r, it is deprecated and always insecure. We
should probably mark it as such in the glibc headers.
OK, I'll just use readdir() then. The directory stream is private to
the library type, so the only way to call readdir() concurrently on a
single directory stream is to increment iterators concurrently, which
is undefined anyway.
So that will work as long as readdir() doesn't use a global static
buffer shared between streams, i.e. it meets the POSIX requirement
that "They shall not be affected by a call to readdir() on a different
directory stream." I don't know if mingw meets that, but there is lots
of work needed to make this stuff work in mingw.
Readdir isn't required to be thread-safe (it may reference global
data) so calling it in multiple threads even with a different dirp
argument is undefined. A thread-unsafe implementation can meet the
POSIX requirement and still access global data but without locking.
The Solaris implementation, for example, is explicitly documented
as thread unsafe.
Martin