[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250423-nolibc-misc-v1-2-a925bf40297b@linutronix.de>
Date: Wed, 23 Apr 2025 17:01:32 +0200
From: Thomas Weißschuh <thomas.weissschuh@...utronix.de>
To: Willy Tarreau <w@....eu>,
Thomas Weißschuh <linux@...ssschuh.net>,
Shuah Khan <shuah@...nel.org>
Cc: linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org,
Thomas Weißschuh <thomas.weissschuh@...utronix.de>
Subject: [PATCH 02/15] 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 <thomas.weissschuh@...utronix.de>
---
tools/include/nolibc/stdio.h | 7 +++++++
tools/testing/selftests/nolibc/nolibc-test.c | 18 ++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index fb0417477759ee6c9663e84807c1d1067e735dec..02426682c34bcd82d9556036c6c3e73a6a5a3b4d 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -17,6 +17,8 @@
#include "string.h"
#include "compiler.h"
+static const char *strerror(int errnum);
+
#ifndef EOF
#define EOF (-1)
#endif
@@ -289,6 +291,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 3e15a25ccddf5135db1f59bce1eefdff2ffe57f6..b7440a667db6b541a2548bdf5182bee0277100ed 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 */
--
2.49.0
Powered by blists - more mailing lists