Re: [PATCH v4 next 09/23] tools/nolibc: Implement strerror() in terms of strerror_r()
From: Willy Tarreau
Date: Sat Mar 07 2026 - 06:37:48 EST
On Sat, Mar 07, 2026 at 11:31:05AM +0000, David Laight wrote:
> On Sat, 7 Mar 2026 11:18:41 +0100
> Willy Tarreau <w@xxxxxx> wrote:
>
> > Hi David,
> >
> > On Mon, Mar 02, 2026 at 10:18:01AM +0000, david.laight.linux@xxxxxxxxx wrote:
> > > From: David Laight <david.laight.linux@xxxxxxxxx>
> > >
> > > strerror() can be the only part of a program that has a .data section.
> > > This requres 4k in the program file.
> >
> > Thanks for handling this one! Indeed, I saw a trivial hello world program
> > take 4kB once %m got supported, which is a shame.
> >
> > > Add a simple implementation of strerror_r() (ignores buflen) and use
> > > that in strerror() so that the "errno=" string is copied at run-time.
> > > Use __builtin_memcpy() because that optimises away the input string
> > > and just writes the required constants to the target buffer.
> > >
> > > Ignoring buflen is unlikely to be a problem given that the output is
> > > always short.
> >
> > On this point it's not necessarily true, as we can overflow too short
> > an output, e.g. when calling strerror_r() on a single-byte buffer:
>
> But that would be silly, and you get what you deserve :-)
> It's not like passing char[64] will be too short because of some overlong
> error text.
Yes I know and I also hate having to write code to defend against
silliness, but sometimes what looks silly to some in fact looks smart
to others. You could for example find it stupid to call snprintf() with
a zero-length but it's actually used sometimes to figure the size to
allocate.
> > > +static __attribute__((unused,))
> > > +int strerror_r(int errnum, char *buf, size_t buflen __attribute__((unused)))
> > > +{
> >
> > Here I think we can simply do this to comply with the man page:
> >
> > if (buflen < 18) {
> > errno = ERANGE;
> > return -1;
>
> Looks like it should 'return ERANGE' (matching glibc 2.13+).
Ah you're right, I initially misunderstood the man page as "a positive
number with errno set". But yes, returning ERANGE is fine!
> > (and we can safely ignore it for strerror()).
>
> ISTR strerror_r() tends to get inlined into strerror() so it
> would be optimised away.
That's what I suspected as well.
> That simple (slightly over-enthusiastic) check is probably fine.
> Especially since normal code will be expecting a much longer string.
>
> I did think of implementing strerror_r() as:
> return snprintf(buf, buflen, "errno=%d", errnum) < buflen ? 0 : ERANGE;
> but that seems excessive.
Yes ;-)
Willy