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.weisssc...@linutronix.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


Reply via email to