Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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@linutronix.de>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://lore.kernel.org/r/20250428-nolibc-misc-v2-2-3c043eeab06c@linutronix.de
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>

authored by

Thomas Weißschuh and committed by
Thomas Weißschuh
7a7cd445 05b6b2a9

+25
+7
tools/include/nolibc/stdio.h
··· 20 20 #include "string.h" 21 21 #include "compiler.h" 22 22 23 + static const char *strerror(int errnum); 24 + 23 25 #ifndef EOF 24 26 #define EOF (-1) 25 27 #endif ··· 294 292 if (!outstr) 295 293 outstr="(null)"; 296 294 } 295 + #ifndef NOLIBC_IGNORE_ERRNO 296 + else if (c == 'm') { 297 + outstr = strerror(errno); 298 + } 299 + #endif /* NOLIBC_IGNORE_ERRNO */ 297 300 else if (c == '%') { 298 301 /* queue it verbatim */ 299 302 continue;
+18
tools/testing/selftests/nolibc/nolibc-test.c
··· 1393 1393 return 0; 1394 1394 } 1395 1395 1396 + int test_strerror(void) 1397 + { 1398 + char buf[100]; 1399 + ssize_t ret; 1400 + 1401 + memset(buf, 'A', sizeof(buf)); 1402 + 1403 + errno = EINVAL; 1404 + ret = snprintf(buf, sizeof(buf), "%m"); 1405 + if (is_nolibc) { 1406 + if (ret < 6 || memcmp(buf, "errno=", 6)) 1407 + return 1; 1408 + } 1409 + 1410 + return 0; 1411 + } 1412 + 1396 1413 static int run_printf(int min, int max) 1397 1414 { 1398 1415 int test; ··· 1438 1421 CASE_TEST(number_width); EXPECT_VFPRINTF(10, " 1", "%10d", 1); break; 1439 1422 CASE_TEST(width_trunc); EXPECT_VFPRINTF(25, " ", "%25d", 1); break; 1440 1423 CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; 1424 + CASE_TEST(strerror); EXPECT_ZR(1, test_strerror()); break; 1441 1425 case __LINE__: 1442 1426 return ret; /* must be last */ 1443 1427 /* note: do not set any defaults so as to permit holes above */