From: Thomas Weißschuh Date: Mon, 28 Apr 2025 12:40:03 +0000 (+0200) Subject: tools/nolibc: add %m printf format X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7a7cd445d9275be8e4650d390156595685c3ac03;p=users%2Fjedix%2Flinux-maple.git tools/nolibc: add %m printf format The %m format can be used to format the current errno. It is non-standard but supported by other commonly used libcs like glibc and musl, so applications do rely on them. Signed-off-by: Thomas Weißschuh Acked-by: Willy Tarreau Link: https://lore.kernel.org/r/20250428-nolibc-misc-v2-2-3c043eeab06c@linutronix.de Signed-off-by: Thomas Weißschuh --- diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 8fa98abab212..df5717d59182 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -20,6 +20,8 @@ #include "string.h" #include "compiler.h" +static const char *strerror(int errnum); + #ifndef EOF #define EOF (-1) #endif @@ -292,6 +294,11 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char if (!outstr) outstr="(null)"; } +#ifndef NOLIBC_IGNORE_ERRNO + else if (c == 'm') { + outstr = strerror(errno); + } +#endif /* NOLIBC_IGNORE_ERRNO */ else if (c == '%') { /* queue it verbatim */ continue; diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index 3e15a25ccddf..b7440a667db6 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1393,6 +1393,23 @@ 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 run_printf(int min, int max) { int test; @@ -1421,6 +1438,7 @@ static int run_printf(int min, int max) CASE_TEST(number_width); EXPECT_VFPRINTF(10, " 1", "%10d", 1); break; CASE_TEST(width_trunc); EXPECT_VFPRINTF(25, " ", "%25d", 1); break; CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; + CASE_TEST(strerror); EXPECT_ZR(1, test_strerror()); break; case __LINE__: return ret; /* must be last */ /* note: do not set any defaults so as to permit holes above */