public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jonathan Wakely <jwakely@redhat.com>
To: Martin Sebor <msebor@gmail.com>
Cc: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: [patch] libstdc++/67747 Allocate space for dirent::d_name
Date: Wed, 30 Sep 2015 12:00:00 -0000	[thread overview]
Message-ID: <20150930110110.GD12094@redhat.com> (raw)
In-Reply-To: <560ADE6F.30104@gmail.com>

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.

>also avoids the TOCTOU between it and the call to opendir, and

Also nice.

>hardcoding the value makes it possible to avoid dynamically
>allocating the dirent buffer.

Can we be sure NAME_MAX will never be too big for the stack?

As currently written _Dir::advance() can call itself recursively to
skip the . and .. directories, so if we put the dirent buffer on the
stack then maybe we should re-use the same one not create three large
frames.

>I didn't remember the MAX_PATH value on Windows anymore but from
>what I've just read online it sounds like it's defined to 260.

Yes, I found that value, but I think I found something saying the
individual components were limited to 255. I'll make it 260 anyway. I
think that might relate to UTF-16 characters, so we'd need a larger
buffer for narrow characters, but I'm not sure what mingw supports
here anyway. The Windows implementations are just stubs where someone
who cares can add working code.

>Defaulting to 255 on POSIX is appropriate. On XSI systems, the
>minimum required value is _XOPEN_NAME_MAX which is 255 (I would
>suggest using the macro instead when it's defined). Otherwise,
>the strictly conforming minimum value would be 14 -- the value
>of _POSIX_NAME_MAX, but since 255 is greater it's fine.
>
>Other than that, I tend to be leery of using plain char arrays
>as buffers for objects of bigger types. I don't know to what
>extent this is a problem for libstdc++ anymore as more and more
>hardware is tolerant of misaligned accesses and as the default
>new expression typically returns memory suitably aligned for
>the largest fundamental type. But since there is no requirement
>in the language that it do so and I would tend to err on the
>side of caution and use operator new (as opposed to
>new char[len]).

For some reason I thought new char[len] would be suitably aligned for
any type with sizeof <= len, but that's only true for operator new.
(I should check I haven't made the same assumption elsewhere in the
library!)

std::aligned_union<offsetof(dirent, d_name)+NAME_MAX, dirent>::type
will give us what we need.


>Martin
>
>PS I'm interpreting _POSIX_NO_TRUNC being zero as more
>restrictive than if it was non-zero and so calling pathconf(p,
>_PC_NO_TRUNC) should be required to also return non-zero for
>such an implementation, regardless of p. But let me check that
>I'm reading it right.
>

  reply	other threads:[~2015-09-30 11:01 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-29 12:00 Jonathan Wakely
2015-09-29 19:49 ` Martin Sebor
2015-09-30 12:00   ` Jonathan Wakely [this message]
2015-09-30 15:54     ` Martin Sebor
2015-10-01 17:23       ` Jonathan Wakely
2015-10-01 18:38         ` Jonathan Wakely
2015-10-01 23:43           ` Jonathan Wakely
2015-10-01 22:56   ` Martin Sebor
2015-10-02 12:16 ` Florian Weimer
2015-10-02 12:34   ` Jonathan Wakely
2015-10-02 12:41     ` Florian Weimer
2015-10-02 16:34       ` Jonathan Wakely
2015-10-02 16:57     ` Martin Sebor
2015-10-02 17:01       ` Jonathan Wakely
2015-10-02 17:09       ` Florian Weimer
2015-10-02 17:38         ` Martin Sebor
2015-10-02 17:43           ` Florian Weimer
2015-10-02 17:53             ` Martin Sebor
2015-10-02 18:03               ` Florian Weimer
2015-10-02 12:37   ` Sebastian Huber
2015-10-02 12:52     ` Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150930110110.GD12094@redhat.com \
    --to=jwakely@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.org \
    --cc=msebor@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).