From: david.laight.linux@gmail.com
To: "Willy Tarreau" <w@1wt.eu>,
"Thomas Weißschuh" <linux@weissschuh.net>,
linux-kernel@vger.kernel.org, "Cheng Li" <lechain@gmail.com>
Cc: David Laight <david.laight.linux@gmail.com>
Subject: [PATCH v5 next 03/17] tools/nolibc: Implement strerror() in terms of strerror_r()
Date: Sun, 8 Mar 2026 11:37:28 +0000 [thread overview]
Message-ID: <20260308113742.12649-4-david.laight.linux@gmail.com> (raw)
In-Reply-To: <20260308113742.12649-1-david.laight.linux@gmail.com>
From: David Laight <david.laight.linux@gmail.com>
strerror() can be the only part of a program that has a .data section.
This requres 4k in the program file.
Add a simple implementation of strerror_r() 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.
Code size change largely depends on whether the inlining decision for
strerror() changes.
Change the tests to use the normal EXPECT_VFPRINTF() when testing %m.
Skip the tests when !is_nolibc.
Acked-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
v5:
- strerror_r() needs to return 0 on success.
- Return ERANGE if the buffer is too short to contain the longest
possible output.
v4:
- Leave the NOLIBC_IGNORE_ERRNO check in __nolibc_printf().
- Don't rename the errno parameter to strerror() in this patch.
tools/include/nolibc/stdio.h | 22 +++++++++++++++++---
tools/testing/selftests/nolibc/nolibc-test.c | 20 ++----------------
2 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index a4df72d9a2d3..af2d5be47aa3 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -722,14 +722,30 @@ int setvbuf(FILE *stream __attribute__((unused)),
return 0;
}
+static __attribute__((unused,))
+int strerror_r(int errnum, char *buf, size_t buflen)
+{
+ if (buflen < 18)
+ return ERANGE;
+
+ __builtin_memcpy(buf, "errno=", 6);
+ i64toa_r(errnum, buf + 6);
+ return 0;
+}
+
static __attribute__((unused))
const char *strerror(int errno)
{
- static char buf[18] = "errno=";
+ static char buf[18];
+ char *b = buf;
+
+ /* Force gcc to use 'register offset' to access buf[]. */
+ _NOLIBC_OPTIMIZER_HIDE_VAR(b);
- i64toa_r(errno, &buf[6]);
+ /* Use strerror_r() to avoid having the only .data in small programs. */
+ strerror_r(errno, b, sizeof(buf));
- return buf;
+ return b;
}
#endif /* _NOLIBC_STDIO_H */
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 9ebebe4ff253..638f18fc5123 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -1786,23 +1786,6 @@ static int test_scanf(void)
return 0;
}
-int test_strerror(void)
-{
- char buf[100];
- ssize_t ret;
-
- memset(buf, 'A', sizeof(buf));
-
- errno = EINVAL;
- ret = snprintf(buf, sizeof(buf), "%m");
- if (is_nolibc) {
- if (ret < 6 || memcmp(buf, "errno=", 6))
- return 1;
- }
-
- return 0;
-}
-
static int test_printf_error(void)
{
int fd, ret, saved_errno;
@@ -1852,8 +1835,9 @@ static int run_printf(int min, int max)
CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1"); break;
CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1); break;
CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " 1", "%25d", 1); break;
+ CASE_TEST(errno); errno = 22; EXPECT_VFPRINTF(is_nolibc, "errno=22", "%m"); break;
+ CASE_TEST(errno-neg); errno = -22; EXPECT_VFPRINTF(is_nolibc, " errno=-22", "%12m"); break;
CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break;
- CASE_TEST(strerror); EXPECT_ZR(1, test_strerror()); break;
CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break;
case __LINE__:
return ret; /* must be last */
--
2.39.5
next prev parent reply other threads:[~2026-03-08 11:37 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-08 11:37 [PATCH v5 next 00/17] Enhance printf() david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 01/17] tools/nolibc: Add _NOLIBC_OPTIMIZER_HIDE_VAR() to compiler.h david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 02/17] selftests/nolibc: Rename w to written in expect_vfprintf() david.laight.linux
2026-03-08 11:37 ` david.laight.linux [this message]
2026-03-08 11:37 ` [PATCH v5 next 04/17] tools/nolibc: Rename the 'errnum' parameter to strerror() david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 05/17] tools/nolibc/printf: Output pad characters in 16 byte chunks david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 06/17] tools/nolibc/printf: Simplify __nolibc_printf() david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 07/17] tools/nolibc/printf: Use goto and reduce indentation david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 08/17] tools/nolibc/printf: Use bit-masks to hold requested flag, length and conversion chars david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 09/17] tools/nolibc/printf: Add support for length modifiers tzqL and formats iX david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 10/17] tools/nolibc/printf: Handle "%s" with the numeric formats david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 11/17] tools/nolibc/printf: Prepend sign to converted number david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 12/17] tools/nolibc/printf: Add support for conversion flags space and plus david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 13/17] tools/nolibc/printf: Special case 0 and add support for %#x david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 14/17] tools/nolibc/printf: Add support for left aligning fields david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 15/17] tools/nolibc/printf: Add support for zero padding and field precision david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 16/17] tools/nolibc/printf: Add support for octal output david.laight.linux
2026-03-08 11:37 ` [PATCH v5 next 17/17] selftests/nolibc: Use printf variable field widths and precisions david.laight.linux
2026-03-08 11:58 ` [PATCH v5 next 00/17] Enhance printf() Willy Tarreau
2026-03-08 21:01 ` Thomas Weißschuh
2026-03-08 22:41 ` David Laight
2026-03-09 6:55 ` Willy Tarreau
2026-03-09 9:20 ` David Laight
2026-03-13 20:07 ` Thomas Weißschuh
2026-03-13 22:40 ` David Laight
2026-03-14 4:48 ` Willy Tarreau
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=20260308113742.12649-4-david.laight.linux@gmail.com \
--to=david.laight.linux@gmail.com \
--cc=lechain@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@weissschuh.net \
--cc=w@1wt.eu \
/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