Re: [PATCH v4 next 09/23] tools/nolibc: Implement strerror() in terms of strerror_r()
From: David Laight
Date: Sat Mar 07 2026 - 06:31:16 EST
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.
>
> > +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+).
> }
>
> (and we can safely ignore it for strerror()).
ISTR strerror_r() tends to get inlined into strerror() so it
would be optimised away.
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.
>
> > + __builtin_memcpy(buf, "errno=", 6);
> > + return 6 + i64toa_r(errnum, buf + 6);
> > +}
> > +
> (...)
>
> Thanks,
> Willy