Add strerrordesc_np() and strerrorname_np().

strerrordesc_np() isn't very useful (being just another name for
strerror()), but strerrorname_np() lets you get "ENOSYS" for ENOSYS,
which will make some of our test assertion messages clearer when we
switch over from strerror().

This also adds `%#m` formatting to all the relevant functions.

Test: treehugger
Change-Id: Icfe07a39a307d591c3f4f2a09d008dc021643062
diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp
index cc1b598..ffb8651 100644
--- a/tests/async_safe_test.cpp
+++ b/tests/async_safe_test.cpp
@@ -79,6 +79,18 @@
   async_safe_format_buffer(buf, sizeof(buf), "a%mZ");
   EXPECT_STREQ("aInvalid argumentZ", buf);
 
+#if __ANDROID_API_LEVEL__ >= 35
+  errno = EINVAL;
+  async_safe_format_buffer(buf, sizeof(buf), "a%#mZ");
+  EXPECT_STREQ("aEINVALZ", buf);
+#endif
+
+#if __ANDROID_API_LEVEL__ >= 35
+  errno = -1;
+  async_safe_format_buffer(buf, sizeof(buf), "a%#mZ");
+  EXPECT_STREQ("a-1Z", buf);
+#endif
+
   async_safe_format_buffer(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
   EXPECT_STREQ("a0xb0001234b", buf);
 
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index b0f59bb..eaacc42 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -2523,6 +2523,24 @@
   EXPECT_SWPRINTF(L"<Invalid argument>", L"<%m>");
 }
 
+TEST(STDIO_TEST, printf_hash_m) {
+  errno = 0;
+  EXPECT_SNPRINTF("<0>", "<%#m>");
+  errno = -1;
+  EXPECT_SNPRINTF("<-1>", "<%#m>");
+  errno = EINVAL;
+  EXPECT_SNPRINTF("<EINVAL>", "<%#m>");
+}
+
+TEST(STDIO_TEST, wprintf_hash_m) {
+  errno = 0;
+  EXPECT_SWPRINTF(L"<0>", L"<%#m>");
+  errno = -1;
+  EXPECT_SWPRINTF(L"<-1>", L"<%#m>");
+  errno = EINVAL;
+  EXPECT_SWPRINTF(L"<EINVAL>", L"<%#m>");
+}
+
 TEST(STDIO_TEST, printf_m_does_not_clobber_strerror) {
   const char* m = strerror(-1);
   ASSERT_STREQ("Unknown error -1", m);
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 38957e2..e7e0f34 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -1685,3 +1685,16 @@
   GTEST_SKIP() << "memset_explicit not available";
 #endif
 }
+
+TEST(STRING_TEST, strerrorname_np) {
+#if defined(__BIONIC__)
+  ASSERT_STREQ("0", strerrorname_np(0));
+  ASSERT_STREQ("EINVAL", strerrorname_np(EINVAL));
+  ASSERT_STREQ("ENOSYS", strerrorname_np(ENOSYS));
+
+  ASSERT_EQ(nullptr, strerrorname_np(-1));
+  ASSERT_EQ(nullptr, strerrorname_np(666));
+#else
+  GTEST_SKIP() << "strerrorname_np not available";
+#endif
+}