[patch] libstdc++/67747 Allocate space for dirent::d_name

Jonathan Wakely jwakely@redhat.com
Thu Oct 1 17:23:00 GMT 2015


On 30/09/15 09:30 -0600, Martin Sebor wrote:
>On 09/30/2015 05:01 AM, Jonathan Wakely wrote:
>>On 29/09/15 12:54 -0600, Martin Sebor wrote:
>>>On 09/29/2015 05:37 AM, 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.
>>>>
>>>>Tested powerpc64le-linux and x86_64-dragonfly4.1, I'm going to commit
>>>>this to trunk today (and backport all the filesystem fixes to
>>>>gcc-5-branch).
>>>
>>>Calling pathconf is only necessary when _POSIX_NO_TRUNC is zero
>>>which I think exists mainly for legacy file systems. Otherwise,
>>>it's safe to use NAME_MAX instead. Avoiding the call to pathconf
>>
>>Oh, nice. I was using NAME_MAX originally but the glibc readdir_r(3)
>>man-page has an example using pathconf and says that should be used,
>>so I went down that route.
>
>GLIBC pathconf calls statfs to get the NAME_MAX value from the OS,
>so there's some chance that some unusual file system will define
>it as greater than 255. I tested all those on my Fedora PC and on
>my RHEL 7.2 powerpc64le box and didn't find one.
>
>There also isn't one in the Wikipedia comparison of file systems:
>  https://en.wikipedia.org/wiki/Comparison_of_file_systems
>
>But to be 100% safe, we would need to call pathconf if readdir
>failed due to truncation.
>
>>Can we be sure NAME_MAX will never be too big for the stack?
>
>When it's defined I think it's probably safe in practice but not
>guaranteed. Also, like all of these <limits.h> constants, it's not
>guaranteed to be defined at all when the implementation doesn't
>impose a limit. I believe AIX is one implementation that doesn't
>define it. So some preprocessor magic will be required to deal
>with that.

OK, latest version attached. This defines a helper type,
dirent_buffer, which either contains aligned_union<N, dirent> or
unique_ptr<void*, op_delete> depending on whether NAME_MAX is defined
or whether we have to use pathconf at run-time.

The dirent_buffer is created as part of the directory_iterator or
recursive_directory_iterator internals, so only once per iterator, and
shared between copies of that iterator. When NAME_MAX is defined there
is no second allocation, we just allocate a bit more space.

Tested powerpc64le-linux and x86_64-dragonfly.

I've started a build on powerpc-aix too but I don't know when the
tests for that will finish.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 6657 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20151001/6fd6c638/attachment.bin>


More information about the Libstdc++ mailing list