Build bionic unit tests for musl

Modify bionic unit tests that are built for glibc so that they also
build against musl.  They don't all pass though:

With glibc:
 2 SLOW TESTS
 4 TIMEOUT TESTS
313 FAILED TESTS
  YOU HAVE 2 DISABLED TESTS

With musl:
11 SLOW TESTS
11 TIMEOUT TESTS
363 FAILED TESTS
  YOU HAVE 2 DISABLED TESTS

Bug: 190084016
Test: m bionic-unit-tests-glibc with musl
Test: atest bionic-unit-tests-static
Test: atest --host bionic-unit-tests-glibc with glibc
Change-Id: I79b6eab04fed3cc4392450df5eef2579412edfe1
diff --git a/tests/Android.bp b/tests/Android.bp
index 0f9af41..1df9264 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -43,6 +43,9 @@
         linux_bionic: {
             header_libs: ["bionic_libc_platform_headers"],
         },
+        musl: {
+            cflags: ["-DMUSL"],
+        },
     },
     cflags: [
         "-fstack-protector-all",
@@ -469,6 +472,18 @@
                 "libsystemproperties",
             ],
         },
+        musl: {
+            exclude_srcs: [
+                // musl doesn't have error.h
+                "error_test.cpp",
+
+                // musl doesn't define noreturn for C++
+                "stdnoreturn_test.cpp",
+
+                // unsupported relocation type 37
+                "ifunc_test.cpp",
+            ],
+        },
     },
 
     static_libs: [
@@ -1171,6 +1186,13 @@
         linux_bionic: {
             enabled: false,
         },
+        musl: {
+            exclude_static_libs: [
+                // Musl doesn't have fortify
+                "libfortify1-tests-clang",
+                "libfortify2-tests-clang",
+            ],
+        },
     },
 }
 
diff --git a/tests/SignalUtils.h b/tests/SignalUtils.h
index a2faf0a..f04ea59 100644
--- a/tests/SignalUtils.h
+++ b/tests/SignalUtils.h
@@ -19,7 +19,7 @@
 #include <signal.h>
 #include <string.h>
 
-#if defined(__GLIBC__)
+#if !defined(__BIONIC__)
 #define posix_spawnattr_getsigdefault64 posix_spawnattr_getsigdefault
 #define posix_spawnattr_getsigmask64 posix_spawnattr_getsigmask
 #define posix_spawnattr_setsigdefault64 posix_spawnattr_setsigdefault
diff --git a/tests/arpa_inet_test.cpp b/tests/arpa_inet_test.cpp
index 8dec2e3..3ee0419 100644
--- a/tests/arpa_inet_test.cpp
+++ b/tests/arpa_inet_test.cpp
@@ -160,6 +160,7 @@
 }
 
 TEST(arpa_inet, inet_nsap_addr) {
+#if !defined(MUSL)
   // inet_nsap_addr() doesn't seem to be documented anywhere, but it's basically
   // text to binary for arbitrarily-long strings like "0xdeadbeef". Any
   // '.', '+', or '/' characters are ignored as punctuation. The return value is
@@ -233,9 +234,13 @@
   ASSERT_EQ(0U, inet_nsap_addr("0x11.2g", buf, sizeof(buf)));
   // Invalid half-byte.
   ASSERT_EQ(0U, inet_nsap_addr("0x11.2", buf, sizeof(buf)));
+#else
+  GTEST_SKIP() << "musl doesn't have inet_nsap_addr";
+#endif
 }
 
 TEST(arpa_inet, inet_nsap_ntoa) {
+#if !defined(MUSL)
   // inet_nsap_ntoa() doesn't seem to be documented anywhere, but it's basically
   // binary to text for arbitrarily-long byte buffers.
   // The return value is a pointer to the buffer. No errors are possible.
@@ -243,10 +248,17 @@
   char dst[32];
   ASSERT_EQ(dst, inet_nsap_ntoa(6, bytes, dst));
   ASSERT_STREQ(dst, "0x01.0002.0EF0.20");
+#else
+  GTEST_SKIP() << "musl doesn't have inet_nsap_ntoa";
+#endif
 }
 
 TEST(arpa_inet, inet_nsap_ntoa__nullptr) {
+#if !defined(MUSL)
   // If you don't provide a destination, a static buffer is provided for you.
   const unsigned char bytes[] = {0x01, 0x00, 0x02, 0x0e, 0xf0, 0x20};
   ASSERT_STREQ("0x01.0002.0EF0.20", inet_nsap_ntoa(6, bytes, nullptr));
+#else
+  GTEST_SKIP() << "musl doesn't have inet_nsap_ntoa";
+#endif
 }
diff --git a/tests/dirent_test.cpp b/tests/dirent_test.cpp
index 56929d1..1155a4e 100644
--- a/tests/dirent_test.cpp
+++ b/tests/dirent_test.cpp
@@ -82,6 +82,7 @@
 }
 
 TEST(dirent, scandirat_scandirat64) {
+#if !defined(MUSL)
   // Get everything from /proc/self...
   dirent** entries;
   int entry_count = scandir("/proc/self", &entries, nullptr, alphasort);
@@ -111,6 +112,9 @@
   ASSERT_EQ(name_set, name_set_at64);
   ASSERT_EQ(unsorted_name_list, unsorted_name_list_at);
   ASSERT_EQ(unsorted_name_list, unsorted_name_list_at64);
+#else
+  GTEST_SKIP() << "musl doesn't have scandirat or scandirat64";
+#endif
 }
 
 static int is_version_filter(const dirent* de) {
@@ -140,6 +144,7 @@
 }
 
 TEST(dirent, scandirat_ENOENT) {
+#if !defined(MUSL)
   int root_fd = open("/", O_DIRECTORY | O_RDONLY);
   ASSERT_NE(-1, root_fd);
   dirent** entries;
@@ -147,9 +152,13 @@
   ASSERT_EQ(-1, scandirat(root_fd, "does-not-exist", &entries, nullptr, nullptr));
   ASSERT_EQ(ENOENT, errno);
   close(root_fd);
+#else
+  GTEST_SKIP() << "musl doesn't have scandirat or scandirat64";
+#endif
 }
 
 TEST(dirent, scandirat64_ENOENT) {
+#if !defined(MUSL)
   int root_fd = open("/", O_DIRECTORY | O_RDONLY);
   ASSERT_NE(-1, root_fd);
   dirent64** entries;
@@ -157,6 +166,9 @@
   ASSERT_EQ(-1, scandirat64(root_fd, "does-not-exist", &entries, nullptr, nullptr));
   ASSERT_EQ(ENOENT, errno);
   close(root_fd);
+#else
+  GTEST_SKIP() << "musl doesn't have scandirat or scandirat64";
+#endif
 }
 
 TEST(dirent, fdopendir_invalid) {
@@ -228,7 +240,7 @@
   CheckProcSelf(name_set);
 }
 
-TEST(dirent, readdir64) {
+TEST(dirent, readdir64_smoke) {
   DIR* d = opendir("/proc/self");
   ASSERT_TRUE(d != nullptr);
   std::set<std::string> name_set;
@@ -263,7 +275,7 @@
   CheckProcSelf(name_set);
 }
 
-TEST(dirent, readdir64_r) {
+TEST(dirent, readdir64_r_smoke) {
   DIR* d = opendir("/proc/self");
   ASSERT_TRUE(d != nullptr);
   std::set<std::string> name_set;
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 35e12eb..6bbe41b 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1156,7 +1156,7 @@
 
 TEST(dlfcn, dlopen_symlink) {
   DlfcnSymlink symlink("dlopen_symlink");
-  const std::string symlink_name = basename(symlink.get_symlink_path().c_str());
+  const std::string symlink_name = android::base::Basename(symlink.get_symlink_path());
   void* handle1 = dlopen("libdlext_test.so", RTLD_NOW);
   void* handle2 = dlopen(symlink_name.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle1 != nullptr);
@@ -1259,6 +1259,7 @@
 }
 
 TEST(dlfcn, dlvsym_smoke) {
+#if !defined(MUSL)
   void* handle = dlopen("libtest_versioned_lib.so", RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
   typedef int (*fn_t)();
@@ -1276,6 +1277,9 @@
   }
 
   dlclose(handle);
+#else
+  GTEST_SKIP() << "musl doesn't have dlvsym";
+#endif
 }
 
 // This preempts the implementation from libtest_versioned_lib.so
diff --git a/tests/elftls_dl_test.cpp b/tests/elftls_dl_test.cpp
index 277b2e3..aa975de 100644
--- a/tests/elftls_dl_test.cpp
+++ b/tests/elftls_dl_test.cpp
@@ -27,9 +27,11 @@
  */
 
 #include <dlfcn.h>
-#include <gtest/gtest.h>
 #include <link.h>
 
+#include <android-base/file.h>
+#include <gtest/gtest.h>
+
 #include <thread>
 
 #include "gtest_globals.h"
@@ -356,7 +358,7 @@
 
       // This test is also run with glibc, where dlpi_name may have relative path components, so
       // examine just the basename when searching for the library.
-      if (strcmp(basename(info->dlpi_name), "libtest_elftls_dynamic.so") != 0) return 0;
+      if (strcmp(android::base::Basename(info->dlpi_name).c_str(), "libtest_elftls_dynamic.so") != 0) return 0;
 
       tls_info.found = true;
       tls_info.modid = info->dlpi_tls_modid;
diff --git a/tests/fcntl_test.cpp b/tests/fcntl_test.cpp
index a8a4cc5..d50a438 100644
--- a/tests/fcntl_test.cpp
+++ b/tests/fcntl_test.cpp
@@ -28,6 +28,8 @@
 // Glibc v2.19 doesn't include these in fcntl.h so host builds will fail without.
 #if !defined(FALLOC_FL_PUNCH_HOLE) || !defined(FALLOC_FL_KEEP_SIZE)
 #include <linux/falloc.h>
+#endif
+#if !defined(EXT4_SUPER_MAGIC)
 #include <linux/magic.h>
 #endif
 
diff --git a/tests/fenv_test.cpp b/tests/fenv_test.cpp
index d495970..ea3f539 100644
--- a/tests/fenv_test.cpp
+++ b/tests/fenv_test.cpp
@@ -170,6 +170,7 @@
 }
 
 TEST(fenv, fedisableexcept_fegetexcept) {
+#if !defined(MUSL)
   feclearexcept(FE_ALL_EXCEPT);
   ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
 
@@ -178,9 +179,13 @@
   ASSERT_EQ(0, fegetexcept());
   ASSERT_EQ(0, feraiseexcept(FE_INVALID));
   ASSERT_EQ(FE_INVALID, fetestexcept(FE_ALL_EXCEPT));
+#else
+  GTEST_SKIP() << "musl doesn't have fegetexcept";
+#endif
 }
 
 TEST(fenv, feenableexcept_fegetexcept) {
+#if !defined(MUSL)
 #if defined(__aarch64__) || defined(__arm__)
   // ARM doesn't support this. They used to if you go back far enough, but it was removed in
   // the Cortex-A8 between r3p1 and r3p2.
@@ -213,4 +218,7 @@
 
   AssertChildExited(pid, -SIGFPE);
 #endif
+#else
+  GTEST_SKIP() << "musl doesn't have fegetexcept";
+#endif
 }
diff --git a/tests/ftw_test.cpp b/tests/ftw_test.cpp
index 200ed4b..6473f71 100644
--- a/tests/ftw_test.cpp
+++ b/tests/ftw_test.cpp
@@ -106,7 +106,7 @@
   ASSERT_EQ(0, ftw(root.path, check_ftw, 128));
 }
 
-TEST(ftw, ftw64) {
+TEST(ftw, ftw64_smoke) {
   TemporaryDir root;
   MakeTree(root.path);
   ASSERT_EQ(0, ftw64(root.path, check_ftw64, 128));
@@ -118,7 +118,7 @@
   ASSERT_EQ(0, nftw(root.path, check_nftw, 128, 0));
 }
 
-TEST(ftw, nftw64) {
+TEST(ftw, nftw64_smoke) {
   TemporaryDir root;
   MakeTree(root.path);
   ASSERT_EQ(0, nftw64(root.path, check_nftw64, 128, 0));
diff --git a/tests/glob_test.cpp b/tests/glob_test.cpp
index b48f2af..8bf35bf 100644
--- a/tests/glob_test.cpp
+++ b/tests/glob_test.cpp
@@ -34,6 +34,7 @@
 // Helper for use with GLOB_ALTDIRFUNC to iterate over the elements of `fake_dir`.
 //
 
+#if !defined(MUSL)
 static std::vector<std::string> fake_dir;
 static size_t fake_dir_offset;
 static void fake_closedir(void*) {
@@ -65,6 +66,7 @@
   g->gl_lstat = fake_lstat;
   g->gl_stat = fake_stat;
 }
+#endif
 
 TEST(glob, glob_result_GLOB_NOMATCH) {
   glob_t g = {};
@@ -102,6 +104,7 @@
   globfree(&g);
 }
 
+#if !defined(MUSL)
 static std::string g_failure_path;
 static int g_failure_errno;
 static int test_error_callback_result;
@@ -110,8 +113,10 @@
   g_failure_errno = failure_errno;
   return test_error_callback_result;
 }
+#endif
 
 TEST(glob, glob_gl_errfunc) {
+#if !defined(MUSL)
   glob_t g = {};
   InstallFake(&g);
 
@@ -126,15 +131,22 @@
   ASSERT_EQ(GLOB_ABORTED, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, test_error_callback, &g));
   ASSERT_EQ("/opendir-fail/", g_failure_path);
   ASSERT_EQ(EINVAL, g_failure_errno);
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
 
 TEST(glob, glob_GLOB_ERR) {
+#if !defined(MUSL)
   glob_t g = {};
   InstallFake(&g);
 
   ASSERT_EQ(GLOB_NOMATCH, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, nullptr, &g));
 
   ASSERT_EQ(GLOB_ABORTED, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC | GLOB_ERR, nullptr, &g));
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
 
 TEST(glob, glob_GLOB_MARK) {
@@ -172,6 +184,7 @@
 }
 
 TEST(glob, glob_GLOB_NOSORT) {
+#if !defined(MUSL)
   fake_dir = { "c", "a", "d", "b" };
 
   glob_t g = {};
@@ -194,9 +207,13 @@
   ASSERT_STREQ("d", g.gl_pathv[2]);
   ASSERT_STREQ("b", g.gl_pathv[3]);
   ASSERT_EQ(nullptr, g.gl_pathv[4]);
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
 
 TEST(glob, glob_GLOB_MAGCHAR) {
+#if !defined(MUSL)
   glob_t g = {};
   ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist", 0, nullptr, &g));
   ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) == 0);
@@ -206,8 +223,12 @@
   // We can lie, but glob(3) will turn that into truth...
   ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist", GLOB_MAGCHAR, nullptr, &g));
   ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) == 0);
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_MAGCHAR";
+#endif
 }
 
+#if !defined(MUSL)
 static void CheckGlob(const char* pattern, const std::vector<std::string>& expected_matches) {
   glob_t g = {};
   InstallFake(&g);
@@ -224,16 +245,22 @@
   }
   globfree(&g);
 }
+#endif
 
 TEST(glob, glob_globbing) {
+#if !defined(MUSL)
   fake_dir = { "f1", "f2", "f30", "f40" };
 
   CheckGlob("f?", { "f1", "f2" });
   CheckGlob("f??", { "f30", "f40" });
   CheckGlob("f*", { "f1", "f2", "f30", "f40" });
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
 
 TEST(glob, glob_globbing_rsc) {
+#if !defined(MUSL)
   // https://research.swtch.com/glob
   fake_dir = { "axbxcxdxe" };
   CheckGlob("a*b*c*d*e*", { "axbxcxdxe" });
@@ -246,4 +273,7 @@
 
   fake_dir = { std::string(100, 'a') };
   CheckGlob("a*a*a*a*b", {});
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
diff --git a/tests/leak_test.cpp b/tests/leak_test.cpp
index 4ebf41f..80618e5 100644
--- a/tests/leak_test.cpp
+++ b/tests/leak_test.cpp
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 #include <sys/user.h>
 #include <unistd.h>
 
@@ -44,7 +45,7 @@
     alive = false;
     for (size_t i = 0; i < tid_count; ++i) {
       if (tids[i] != 0) {
-        if (tgkill(getpid(), tids[i], 0) == 0) {
+        if (syscall(__NR_tgkill, getpid(), tids[i], 0) == 0) {
           alive = true;
         } else {
           EXPECT_EQ(errno, ESRCH);
diff --git a/tests/libgen_basename_test.cpp b/tests/libgen_basename_test.cpp
index 91ae960..1202af6 100644
--- a/tests/libgen_basename_test.cpp
+++ b/tests/libgen_basename_test.cpp
@@ -18,6 +18,7 @@
   #define _GNU_SOURCE 1
 #endif
 
+#if !defined(MUSL)
 #include <string.h>
 
 #if defined(basename)
@@ -28,9 +29,11 @@
   return basename(in);
 }
 
+#endif
+
 #include <libgen.h>
 
-#if !defined(basename)
+#if !defined(basename) && !defined(MUSL)
   #error basename should be defined at this point
 #endif
 
@@ -41,12 +44,14 @@
 #include <errno.h>
 #include <gtest/gtest.h>
 
+#if !defined(MUSL)
 static void __TestGnuBasename(const char* in, const char* expected_out, int line) {
   errno = 0;
   const char* out = gnu_basename(in);
   ASSERT_STREQ(expected_out, out) << "(" << line << "): " << in << std::endl;
   ASSERT_EQ(0, errno) << "(" << line << "): " << in << std::endl;
 }
+#endif
 
 static void __TestPosixBasename(const char* in, const char* expected_out, int line) {
   char* writable_in = (in != nullptr) ? strdup(in) : nullptr;
@@ -61,6 +66,7 @@
 #define TestPosixBasename(in, expected) __TestPosixBasename(in, expected, __LINE__)
 
 TEST(libgen_basename, gnu_basename) {
+#if !defined(MUSL)
   // GNU's basename doesn't accept NULL
   // TestGnuBasename(NULL, ".");
   TestGnuBasename("", "");
@@ -73,6 +79,9 @@
   TestGnuBasename("..", "..");
   TestGnuBasename("///", "");
   TestGnuBasename("//usr//lib//", "");
+#else
+  GTEST_SKIP() << "musl doesn't have GNU basename";
+  #endif
 }
 
 TEST(libgen_basename, posix_basename) {
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 30da5c3..f15fc75 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -55,10 +55,14 @@
 
 #define HAVE_REALLOCARRAY 1
 
-#else
+#elif defined(__GLIBC__)
 
 #define HAVE_REALLOCARRAY __GLIBC_PREREQ(2, 26)
 
+#elif defined(MUSL)
+
+#define HAVE_REALLOCARRAY 1
+
 #endif
 
 TEST(malloc, malloc_std) {
@@ -655,10 +659,14 @@
 }
 
 TEST(malloc, mallopt_smoke) {
+#if !defined(MUSL)
   errno = 0;
   ASSERT_EQ(0, mallopt(-1000, 1));
   // mallopt doesn't set errno.
   ASSERT_EQ(0, errno);
+#else
+  GTEST_SKIP() << "musl doesn't have mallopt";
+#endif
 }
 
 TEST(malloc, mallopt_decay) {
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 9f7e65b..c53741c 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -201,7 +201,7 @@
 }
 
 TEST(MATH_TEST, __fpclassifyd) {
-#if defined(__GLIBC__)
+#if defined(__GLIBC__) || defined(MUSL)
 #define __fpclassifyd __fpclassify
 #endif
   ASSERT_EQ(FP_INFINITE, __fpclassifyd(HUGE_VAL));
@@ -246,6 +246,8 @@
 TEST(MATH_TEST, __isfinite) {
 #if defined(__GLIBC__)
 #define __isfinite __finite
+#elif defined(MUSL)
+#define __isfinite isfinite
 #endif
   ASSERT_TRUE(__isfinite(123.0));
   ASSERT_FALSE(__isfinite(HUGE_VAL));
@@ -255,6 +257,8 @@
 TEST(MATH_TEST, __isfinitef) {
 #if defined(__GLIBC__)
 #define __isfinitef __finitef
+#elif defined(MUSL)
+#define __isfinitef isfinite
 #endif
   ASSERT_TRUE(__isfinitef(123.0f));
   ASSERT_FALSE(__isfinitef(HUGE_VALF));
@@ -264,6 +268,8 @@
 TEST(MATH_TEST, isfinitef) {
 #if defined(__GLIBC__)
 #define isfinitef __finitef
+#elif defined(MUSL)
+#define isfinitef isfinite
 #endif
   ASSERT_TRUE(isfinitef(123.0f));
   ASSERT_FALSE(isfinitef(HUGE_VALF));
@@ -273,6 +279,8 @@
 TEST(MATH_TEST, __isfinitel) {
 #if defined(__GLIBC__)
 #define __isfinitel __finitel
+#elif defined(MUSL)
+#define __isfinitel isfinite
 #endif
   ASSERT_TRUE(__isfinitel(123.0L));
   ASSERT_FALSE(__isfinitel(HUGE_VALL));
@@ -282,6 +290,8 @@
 TEST(MATH_TEST, isfinitel) {
 #if defined(__GLIBC__)
 #define isfinitel __finitel
+#elif defined(MUSL)
+#define isfinitel isfinite
 #endif
   ASSERT_TRUE(isfinitel(123.0L));
   ASSERT_FALSE(isfinitel(HUGE_VALL));
@@ -309,30 +319,45 @@
 extern "C" int isinfl(long double);
 
 TEST(MATH_TEST, __isinf) {
+#if defined(MUSL)
+#define __isinf isinf
+#endif
   ASSERT_FALSE(__isinf(123.0));
   ASSERT_TRUE(__isinf(HUGE_VAL));
   ASSERT_TRUE(__isinf(-HUGE_VAL));
 }
 
 TEST(MATH_TEST, __isinff) {
+#if defined(MUSL)
+#define __isinff isinf
+#endif
   ASSERT_FALSE(__isinff(123.0f));
   ASSERT_TRUE(__isinff(HUGE_VALF));
   ASSERT_TRUE(__isinff(-HUGE_VALF));
 }
 
 TEST(MATH_TEST, isinff) {
+#if defined(MUSL)
+#define isinff isinf
+#endif
   ASSERT_FALSE(isinff(123.0f));
   ASSERT_TRUE(isinff(HUGE_VALF));
   ASSERT_TRUE(isinff(-HUGE_VALF));
 }
 
 TEST(MATH_TEST, __isinfl) {
+#if defined(MUSL)
+#define __isinfl isinf
+#endif
   ASSERT_FALSE(__isinfl(123.0L));
   ASSERT_TRUE(__isinfl(HUGE_VALL));
   ASSERT_TRUE(__isinfl(-HUGE_VALL));
 }
 
 TEST(MATH_TEST, isinfl) {
+#if defined(MUSL)
+#define isinfl isinf
+#endif
   ASSERT_FALSE(isinfl(123.0L));
   ASSERT_TRUE(isinfl(HUGE_VALL));
   ASSERT_TRUE(isinfl(-HUGE_VALL));
@@ -352,26 +377,41 @@
 extern "C" int isnanl(long double);
 
 TEST(MATH_TEST, __isnan) {
+#if defined(MUSL)
+#define __isnan isnan
+#endif
   ASSERT_FALSE(__isnan(123.0));
   ASSERT_TRUE(__isnan(nan("")));
 }
 
 TEST(MATH_TEST, __isnanf) {
+#if defined(MUSL)
+#define __isnanf isnan
+#endif
   ASSERT_FALSE(__isnanf(123.0f));
   ASSERT_TRUE(__isnanf(nanf("")));
 }
 
 TEST(MATH_TEST, isnanf) {
+#if defined(MUSL)
+#define isnanf isnan
+#endif
   ASSERT_FALSE(isnanf(123.0f));
   ASSERT_TRUE(isnanf(nanf("")));
 }
 
 TEST(MATH_TEST, __isnanl) {
+#if defined(MUSL)
+#define __isnanl isnan
+#endif
   ASSERT_FALSE(__isnanl(123.0L));
   ASSERT_TRUE(__isnanl(nanl("")));
 }
 
 TEST(MATH_TEST, isnanl) {
+#if defined(MUSL)
+#define isnanl isnan
+#endif
   ASSERT_FALSE(isnanl(123.0L));
   ASSERT_TRUE(isnanl(nanl("")));
 }
@@ -1345,11 +1385,16 @@
 }
 
 TEST(MATH_TEST, significandl) {
+#if !defined(MUSL)
   ASSERT_DOUBLE_EQ(0.0L, significandl(0.0L));
   ASSERT_DOUBLE_EQ(1.2L, significandl(1.2L));
   ASSERT_DOUBLE_EQ(1.53125L, significandl(12.25L));
+#else
+  GTEST_SKIP() << "musl doesn't have significandl";
+#endif
 }
 
+
 TEST(MATH_TEST, scalb) {
   ASSERT_DOUBLE_EQ(12.0, scalb(3.0, 2.0));
 }
@@ -1383,11 +1428,19 @@
 }
 
 TEST(MATH_TEST, gamma) {
+#if !defined(MUSL)
   ASSERT_DOUBLE_EQ(log(24.0), gamma(5.0));
+#else
+  GTEST_SKIP() << "musl doesn't have gamma";
+#endif
 }
 
 TEST(MATH_TEST, gammaf) {
+#if !defined(MUSL)
   ASSERT_FLOAT_EQ(logf(24.0f), gammaf(5.0f));
+#else
+  GTEST_SKIP() << "musl doesn't have gammaf";
+#endif
 }
 
 TEST(MATH_TEST, gamma_r) {
diff --git a/tests/netdb_test.cpp b/tests/netdb_test.cpp
index a805693..0205707 100644
--- a/tests/netdb_test.cpp
+++ b/tests/netdb_test.cpp
@@ -265,11 +265,18 @@
   ASSERT_EQ(0, hp->h_addr[0]);
 }
 
+#if defined(MUSL)
+// musl doesn't define NETDB_INTERNAL.  It also never sets *err to -1, but
+// since gethostbyname_r is a glibc extension, the difference in behavior
+// between musl and  glibc should probably be considered a bug in musl.
+#define NETDB_INTERNAL -1
+#endif
+
 TEST(netdb, gethostbyname_r_ERANGE) {
   hostent hent;
   hostent *hp;
   char buf[4]; // Use too small buffer.
-  int err;
+  int err = 0;
   int result = gethostbyname_r("localhost", &hent, buf, sizeof(buf), &hp, &err);
   EXPECT_EQ(NETDB_INTERNAL, err);
   EXPECT_EQ(ERANGE, result);
@@ -280,7 +287,7 @@
   hostent hent;
   hostent *hp;
   char buf[4]; // Use too small buffer.
-  int err;
+  int err = 0;
   int result = gethostbyname2_r("localhost", AF_INET, &hent, buf, sizeof(buf), &hp, &err);
   EXPECT_EQ(NETDB_INTERNAL, err);
   EXPECT_EQ(ERANGE, result);
@@ -292,7 +299,7 @@
   hostent hent;
   hostent *hp;
   char buf[4]; // Use too small buffer.
-  int err;
+  int err = 0;
   int result = gethostbyaddr_r(&addr, sizeof(addr), AF_INET, &hent, buf, sizeof(buf), &hp, &err);
   EXPECT_EQ(NETDB_INTERNAL, err);
   EXPECT_EQ(ERANGE, result);
diff --git a/tests/netinet_in_test.cpp b/tests/netinet_in_test.cpp
index 437e180..8343f57 100644
--- a/tests/netinet_in_test.cpp
+++ b/tests/netinet_in_test.cpp
@@ -31,6 +31,7 @@
 static constexpr uint64_t be64 = 0xf0debc9a78563412;
 
 TEST(netinet_in, bindresvport) {
+#if !defined(MUSL)
   // This isn't something we can usually test (because you need to be root),
   // so just check the symbol's there.
   ASSERT_EQ(-1, bindresvport(-1, nullptr));
@@ -40,6 +41,9 @@
   errno = 0;
   ASSERT_EQ(-1, bindresvport(-1, &sin));
   ASSERT_EQ(EPFNOSUPPORT, errno);
+#else
+  GTEST_SKIP() << "musl doesn't support bindresvport";
+#endif
 }
 
 TEST(netinet_in, in6addr_any) {
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 1a00460..3686ffb 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -844,6 +844,8 @@
     ASSERT_EQ(pshared_value_array[i], pshared);
   }
 
+#if !defined(MUSL)
+  // musl doesn't have pthread_rwlockattr_setkind_np
   int kind_array[] = {PTHREAD_RWLOCK_PREFER_READER_NP,
                       PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP};
   for (size_t i = 0; i < sizeof(kind_array) / sizeof(kind_array[0]); ++i) {
@@ -852,6 +854,7 @@
     ASSERT_EQ(0, pthread_rwlockattr_getkind_np(&attr, &kind));
     ASSERT_EQ(kind_array[i], kind);
   }
+#endif
 
   ASSERT_EQ(0, pthread_rwlockattr_destroy(&attr));
 }
@@ -1235,6 +1238,8 @@
 #endif  // __BIONIC__
 }
 
+#if !defined(MUSL)
+// musl doesn't have pthread_rwlockattr_setkind_np
 class RwlockKindTestHelper {
  private:
   struct ThreadArg {
@@ -1302,8 +1307,10 @@
     delete arg;
   }
 };
+#endif
 
 TEST(pthread, pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_READER_NP) {
+#if !defined(MUSL)
   RwlockKindTestHelper helper(PTHREAD_RWLOCK_PREFER_READER_NP);
   ASSERT_EQ(0, pthread_rwlock_rdlock(&helper.lock));
 
@@ -1319,9 +1326,13 @@
 
   ASSERT_EQ(0, pthread_rwlock_unlock(&helper.lock));
   ASSERT_EQ(0, pthread_join(writer_thread, nullptr));
+#else
+  GTEST_SKIP() << "musl doesn't have pthread_rwlockattr_setkind_np";
+#endif
 }
 
 TEST(pthread, pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) {
+#if !defined(MUSL)
   RwlockKindTestHelper helper(PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
   ASSERT_EQ(0, pthread_rwlock_rdlock(&helper.lock));
 
@@ -1338,6 +1349,9 @@
   ASSERT_EQ(0, pthread_rwlock_unlock(&helper.lock));
   ASSERT_EQ(0, pthread_join(writer_thread, nullptr));
   ASSERT_EQ(0, pthread_join(reader_thread, nullptr));
+#else
+  GTEST_SKIP() << "musl doesn't have pthread_rwlockattr_setkind_np";
+#endif
 }
 
 static int g_once_fn_call_count = 0;
@@ -2152,6 +2166,9 @@
   ASSERT_EQ(0, memcmp(&lock_normal, &m1.lock, sizeof(pthread_mutex_t)));
   pthread_mutex_destroy(&lock_normal);
 
+#if !defined(MUSL)
+  // musl doesn't support PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP or
+  // PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.
   pthread_mutex_t lock_errorcheck = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
   PthreadMutex m2(PTHREAD_MUTEX_ERRORCHECK);
   ASSERT_EQ(0, memcmp(&lock_errorcheck, &m2.lock, sizeof(pthread_mutex_t)));
@@ -2161,6 +2178,7 @@
   PthreadMutex m3(PTHREAD_MUTEX_RECURSIVE);
   ASSERT_EQ(0, memcmp(&lock_recursive, &m3.lock, sizeof(pthread_mutex_t)));
   ASSERT_EQ(0, pthread_mutex_destroy(&lock_recursive));
+#endif
 }
 
 class MutexWakeupHelper {
diff --git a/tests/resolv_test.cpp b/tests/resolv_test.cpp
index 5743239..7f1f03e 100644
--- a/tests/resolv_test.cpp
+++ b/tests/resolv_test.cpp
@@ -31,6 +31,7 @@
 #include <gtest/gtest.h>
 
 TEST(resolv, b64_pton_28035006) {
+#if !defined(MUSL)
   // Test data from https://groups.google.com/forum/#!topic/mailing.openbsd.tech/w3ACIlklJkI.
   const char* data =
       "p1v3+nehH3N3n+/OokzXpsyGF2VVpxIxkjSn3Mv/Sq74OE1iFuVU+K4bQImuVj"
@@ -41,32 +42,51 @@
   // incorrectly required an extra byte. http://b/28035006.
   uint8_t buf[128];
   ASSERT_EQ(128, b64_pton(data, buf, sizeof(buf)));
+#else
+  GTEST_SKIP() << "musl doesn't have b64_pton";
+#endif
 }
 
 TEST(resolv, b64_ntop) {
+#if !defined(MUSL)
   char buf[128];
   memset(buf, 'x', sizeof(buf));
   ASSERT_EQ(static_cast<int>(strlen("aGVsbG8=")),
             b64_ntop(reinterpret_cast<u_char const*>("hello"), strlen("hello"),
                      buf, sizeof(buf)));
   ASSERT_STREQ(buf, "aGVsbG8=");
+#else
+  GTEST_SKIP() << "musl doesn't have b64_ntop";
+#endif
 }
 
 TEST(resolv, b64_pton) {
+#if !defined(MUSL)
   u_char buf[128];
   memset(buf, 'x', sizeof(buf));
   ASSERT_EQ(static_cast<int>(strlen("hello")), b64_pton("aGVsbG8=", buf, sizeof(buf)));
   ASSERT_STREQ(reinterpret_cast<char*>(buf), "hello");
+#else
+  GTEST_SKIP() << "musl doesn't have b64_pton";
+#endif
 }
 
 TEST(resolv, p_class) {
+#if !defined(MUSL)
   ASSERT_STREQ("IN", p_class(ns_c_in));
   ASSERT_STREQ("BADCLASS", p_class(-1));
+#else
+  GTEST_SKIP() << "musl doesn't have p_class";
+#endif
 }
 
 TEST(resolv, p_type) {
+#if !defined(MUSL)
   ASSERT_STREQ("AAAA", p_type(ns_t_aaaa));
   ASSERT_STREQ("BADTYPE", p_type(-1));
+#else
+  GTEST_SKIP() << "musl doesn't have p_type";
+#endif
 }
 
 TEST(resolv, res_init) {
@@ -74,5 +94,9 @@
 }
 
 TEST(resolv, res_randomid) {
+#if !defined(MUSL)
   res_randomid();
+#else
+  GTEST_SKIP() << "musl doesn't have res_randomid";
+#endif
 }
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index ffbb667..08c21b4 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -554,8 +554,12 @@
 }
 
 TEST(signal, sys_siglist) {
+#if !defined(MUSL)
   ASSERT_TRUE(sys_siglist[0] == nullptr);
   ASSERT_STREQ("Hangup", sys_siglist[SIGHUP]);
+#else
+  GTEST_SKIP() << "musl doesn't have sys_siglist";
+#endif
 }
 
 TEST(signal, limits) {
@@ -582,7 +586,7 @@
 
 TEST(signal, sigqueue) {
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   errno = 0;
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
   ASSERT_EQ(0, errno);
@@ -590,17 +594,22 @@
 }
 
 TEST(signal, pthread_sigqueue_self) {
+#if !defined(MUSL)
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   errno = 0;
   ASSERT_EQ(0, pthread_sigqueue(pthread_self(), SIGALRM, sigval));
   ASSERT_EQ(0, errno);
   ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
+#else
+  GTEST_SKIP() << "musl doesn't have pthread_sigqueue";
+#endif
 }
 
 TEST(signal, pthread_sigqueue_other) {
+#if !defined(MUSL)
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
 
   sigset_t mask;
   sigfillset(&mask);
@@ -621,6 +630,9 @@
   ASSERT_EQ(0, errno);
   pthread_join(thread, nullptr);
   ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
+#else
+  GTEST_SKIP() << "musl doesn't have pthread_sigqueue";
+#endif
 }
 
 TEST(signal, sigwait_SIGALRM) {
@@ -633,7 +645,7 @@
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
 
   // Get pending SIGALRM.
@@ -652,7 +664,7 @@
   ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
 
   // Raise SIGRTMIN.
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
 
   // Get pending SIGRTMIN.
@@ -671,7 +683,7 @@
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
 
   // Get pending SIGALRM.
@@ -693,7 +705,7 @@
   ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
 
   // Raise SIGRTMIN.
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
 
   // Get pending SIGRTMIN.
@@ -715,7 +727,7 @@
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval = { .sival_int = 1 };
+  sigval sigval = { .sival_int = 1 };
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
 
   // Get pending SIGALRM.
@@ -736,7 +748,7 @@
   ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval = { .sival_int = 1 };
+  sigval sigval = { .sival_int = 1 };
   ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
 
   // Get pending SIGALRM.
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index d7ed970..3309466 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -31,7 +31,7 @@
 # if !defined(POSIX_SPAWN_SETSID)
 #  define POSIX_SPAWN_SETSID 0
 # endif
-#else
+#elif defined(__BIONIC__)
 #include <platform/bionic/reserved_signals.h>
 #endif
 
@@ -379,7 +379,7 @@
 }
 
 TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGMASK) {
-#if defined(__GLIBC__)
+#if defined(__GLIBC__) || defined(MUSL)
   GTEST_SKIP() << "glibc doesn't ignore the same signals.";
 #else
   // Block SIGBUS in the parent...
@@ -417,7 +417,7 @@
 }
 
 TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGDEF) {
-#if defined(__GLIBC__)
+#if defined(__GLIBC__) || defined(MUSL)
   GTEST_SKIP() << "glibc doesn't ignore the same signals.";
 #else
   // Ignore SIGALRM and SIGCONT in the parent...
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 5736e17..9d840f5 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -2740,8 +2740,8 @@
 }
 
 TEST(STDIO_TEST, renameat2) {
-#if defined(__GLIBC__)
-  GTEST_SKIP() << "glibc doesn't have renameat2 until 2.28";
+#if defined(__GLIBC__) || defined(MUSL)
+  GTEST_SKIP() << "glibc doesn't have renameat2 until 2.28 and musl doesn't have renameat2";
 #else
   TemporaryDir td;
   android::base::unique_fd dirfd{open(td.path, O_PATH)};
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 6c7966d..5b81834 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -454,7 +454,7 @@
   ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
 }
 
-TEST(stdlib, mkostemp64) {
+TEST(stdlib, mkostemp64_smoke) {
   MyTemporaryFile tf([](char* path) { return mkostemp64(path, O_CLOEXEC); });
   ASSERT_TRUE(CloseOnExec(tf.fd));
 }
@@ -464,7 +464,7 @@
   ASSERT_TRUE(CloseOnExec(tf.fd));
 }
 
-TEST(stdlib, mkstemp64) {
+TEST(stdlib, mkstemp64_smoke) {
   MyTemporaryFile tf(mkstemp64);
   struct stat64 sb;
   ASSERT_EQ(0, fstat64(tf.fd, &sb));
@@ -632,6 +632,13 @@
   AssertChildExited(pid, 99);
 }
 
+#if defined(MUSL)
+// musl doesn't have getpt
+int getpt() {
+  return posix_openpt(O_RDWR|O_NOCTTY);
+}
+#endif
+
 TEST(stdlib, pty_smoke) {
   // getpt returns a pty with O_RDWR|O_NOCTTY.
   int fd = getpt();
@@ -961,8 +968,8 @@
 }
 
 TEST(stdlib, getprogname) {
-#if defined(__GLIBC__)
-  GTEST_SKIP() << "glibc doesn't have getprogname()";
+#if defined(__GLIBC__) || defined(MUSL)
+  GTEST_SKIP() << "glibc and musl don't have getprogname()";
 #else
   // You should always have a name.
   ASSERT_TRUE(getprogname() != nullptr);
@@ -972,8 +979,8 @@
 }
 
 TEST(stdlib, setprogname) {
-#if defined(__GLIBC__)
-  GTEST_SKIP() << "glibc doesn't have setprogname()";
+#if defined(__GLIBC__) || defined(MUSL)
+  GTEST_SKIP() << "glibc and musl don't have setprogname()";
 #else
   // setprogname() only takes the basename of what you give it.
   setprogname("/usr/bin/muppet");
diff --git a/tests/string_posix_strerror_r_test.cpp b/tests/string_posix_strerror_r_test.cpp
index c4757ae..f3d73d4 100644
--- a/tests/string_posix_strerror_r_test.cpp
+++ b/tests/string_posix_strerror_r_test.cpp
@@ -27,16 +27,28 @@
 
   // Valid.
   ASSERT_EQ(0, posix_strerror_r(0, buf, sizeof(buf)));
+#if defined(MUSL)
+  ASSERT_STREQ("No error information", buf);
+#else
   ASSERT_STREQ("Success", buf);
+#endif
   ASSERT_EQ(0, posix_strerror_r(1, buf, sizeof(buf)));
   ASSERT_STREQ("Operation not permitted", buf);
 
-#if defined(__BIONIC__)
+#if defined(__BIONIC__) || defined(MUSL)
   // Invalid.
   ASSERT_EQ(0, posix_strerror_r(-1, buf, sizeof(buf)));
+# if defined(__BIONIC__)
   ASSERT_STREQ("Unknown error -1", buf);
+# else
+  ASSERT_STREQ("No error information", buf);
+# endif
   ASSERT_EQ(0, posix_strerror_r(1234, buf, sizeof(buf)));
+# if defined(__BIONIC__)
   ASSERT_STREQ("Unknown error 1234", buf);
+# else
+  ASSERT_STREQ("No error information", buf);
+# endif
 #else
   // glibc returns EINVAL for unknown errors
   ASSERT_EQ(EINVAL, posix_strerror_r(-1, buf, sizeof(buf)));
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 22be852..d19b60d 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -95,6 +95,7 @@
 }
 
 TEST(STRING_TEST, gnu_strerror_r) {
+#if !defined(MUSL)
   char buf[256];
 
   // Note that glibc doesn't necessarily write into the buffer.
@@ -122,6 +123,9 @@
   ASSERT_STREQ("U", buf);
   // The GNU strerror_r doesn't set errno (the POSIX one sets it to ERANGE).
   ASSERT_EQ(0, errno);
+#else
+  GTEST_SKIP() << "musl doesn't have GNU strerror_r";
+#endif
 }
 
 TEST(STRING_TEST, strsignal) {
@@ -1473,14 +1477,17 @@
   RunSingleBufferOverreadTest(DoStrrchrTest);
 }
 
+#if !defined(MUSL)
 static void TestBasename(const char* in, const char* expected_out) {
   errno = 0;
   const char* out = basename(in);
   ASSERT_STREQ(expected_out, out) << in;
   ASSERT_EQ(0, errno) << in;
 }
+#endif
 
 TEST(STRING_TEST, __gnu_basename) {
+#if !defined(MUSL)
   TestBasename("", "");
   TestBasename("/usr/lib", "lib");
   TestBasename("/usr/", "");
@@ -1490,6 +1497,9 @@
   TestBasename("..", "..");
   TestBasename("///", "");
   TestBasename("//usr//lib//", "");
+#else
+  GTEST_SKIP() << "musl doesn't have GNU basename";
+#endif
 }
 
 TEST(STRING_TEST, strnlen_147048) {
diff --git a/tests/sys_procfs_test.cpp b/tests/sys_procfs_test.cpp
index 5e0a0b0..4a64742 100644
--- a/tests/sys_procfs_test.cpp
+++ b/tests/sys_procfs_test.cpp
@@ -16,6 +16,7 @@
 
 #include <gtest/gtest.h>
 
+#include <ucontext.h> // for NGREG on musl
 #include <sys/procfs.h>
 
 TEST(sys_procfs, types) {
diff --git a/tests/sys_resource_test.cpp b/tests/sys_resource_test.cpp
index b1e8b1a..0247fcb 100644
--- a/tests/sys_resource_test.cpp
+++ b/tests/sys_resource_test.cpp
@@ -89,7 +89,7 @@
   ASSERT_EQ(123U, l32_.rlim_cur);
 }
 
-TEST_F(SysResourceTest, setrlimit64) {
+TEST_F(SysResourceTest, setrlimit64_smoke) {
   l64_.rlim_cur = 456U;
   ASSERT_EQ(0, setrlimit64(RLIMIT_CORE, &l64_));
   CheckResourceLimits();
@@ -103,7 +103,7 @@
   ASSERT_EQ(pr_l32_.rlim_max, pr_l32_.rlim_cur);
 }
 
-TEST_F(SysResourceTest, prlimit64) {
+TEST_F(SysResourceTest, prlimit64_smoke) {
   pr_l64_.rlim_cur = pr_l64_.rlim_max;
   ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, &pr_l64_, nullptr));
   CheckResourceLimits();
diff --git a/tests/sys_sendfile_test.cpp b/tests/sys_sendfile_test.cpp
index 4cddd0d..1ec6c9f 100644
--- a/tests/sys_sendfile_test.cpp
+++ b/tests/sys_sendfile_test.cpp
@@ -43,7 +43,7 @@
   ASSERT_STREQ("ll", buf);
 }
 
-TEST(sys_sendfile, sendfile64) {
+TEST(sys_sendfile, sendfile64_smoke) {
   TemporaryFile src_file;
   ASSERT_EQ(5, TEMP_FAILURE_RETRY(write(src_file.fd, "hello", 5)));
 
diff --git a/tests/sys_statvfs_test.cpp b/tests/sys_statvfs_test.cpp
index bff9e20..1761e6a 100644
--- a/tests/sys_statvfs_test.cpp
+++ b/tests/sys_statvfs_test.cpp
@@ -43,7 +43,7 @@
   Check(sb);
 }
 
-TEST(sys_statvfs, statvfs64) {
+TEST(sys_statvfs, statvfs64_smoke) {
   struct statvfs64 sb;
   ASSERT_EQ(0, statvfs64("/proc", &sb));
   Check(sb);
@@ -57,7 +57,7 @@
   Check(sb);
 }
 
-TEST(sys_statvfs, fstatvfs64) {
+TEST(sys_statvfs, fstatvfs64_smoke) {
   struct statvfs64 sb;
   int fd = open("/proc", O_RDONLY);
   ASSERT_EQ(0, fstatvfs64(fd, &sb));
diff --git a/tests/sys_types_test.cpp b/tests/sys_types_test.cpp
index 0793be2..0559664 100644
--- a/tests/sys_types_test.cpp
+++ b/tests/sys_types_test.cpp
@@ -16,6 +16,7 @@
 
 #include <gtest/gtest.h>
 
+#include <fcntl.h> // for loff_t on musl
 #include <sys/types.h>
 
 TEST(sys_types, type_sizes) {
diff --git a/tests/sys_vfs_test.cpp b/tests/sys_vfs_test.cpp
index f82f505..242f8d4 100644
--- a/tests/sys_vfs_test.cpp
+++ b/tests/sys_vfs_test.cpp
@@ -51,7 +51,7 @@
   ASSERT_EQ(ENOENT, errno);
 }
 
-TEST(sys_vfs, statfs64) {
+TEST(sys_vfs, statfs64_smoke) {
   struct statfs64 sb;
   ASSERT_EQ(0, statfs64("/proc", &sb));
   Check(sb);
@@ -79,7 +79,7 @@
   ASSERT_EQ(EBADF, errno);
 }
 
-TEST(sys_vfs, fstatfs64) {
+TEST(sys_vfs, fstatfs64_smoke) {
   struct statfs64 sb;
   int fd = open("/proc", O_RDONLY);
   ASSERT_EQ(0, fstatfs64(fd, &sb));
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index b16fe16..932af9e 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -282,6 +282,7 @@
 }
 
 TEST(time, strptime_l) {
+#if !defined(MUSL)
   setenv("TZ", "UTC", 1);
 
   struct tm t;
@@ -296,6 +297,9 @@
   strptime_l("09:41:53", "%T", &t, LC_GLOBAL_LOCALE);
   strftime_l(buf, sizeof(buf), "%H:%M:%S", &t, LC_GLOBAL_LOCALE);
   EXPECT_STREQ("09:41:53", buf);
+#else
+  GTEST_SKIP() << "musl doesn't support strptime_l";
+#endif
 }
 
 TEST(time, strptime_F) {
@@ -469,11 +473,11 @@
   ASSERT_EQ(0, timer_settime(t, 0, &ts, nullptr));
 }
 
-static void NoOpNotifyFunction(sigval_t) {
+static void NoOpNotifyFunction(sigval) {
 }
 
 TEST(time, timer_create) {
-  sigevent_t se;
+  sigevent se;
   memset(&se, 0, sizeof(se));
   se.sigev_notify = SIGEV_THREAD;
   se.sigev_notify_function = NoOpNotifyFunction;
@@ -502,7 +506,7 @@
 }
 
 TEST(time, timer_create_SIGEV_SIGNAL) {
-  sigevent_t se;
+  sigevent se;
   memset(&se, 0, sizeof(se));
   se.sigev_notify = SIGEV_SIGNAL;
   se.sigev_signo = SIGUSR1;
@@ -530,7 +534,7 @@
  private:
   std::atomic<int> value;
   timer_t timer_id;
-  sigevent_t se;
+  sigevent se;
   bool timer_valid;
 
   void Create() {
@@ -540,7 +544,7 @@
   }
 
  public:
-  explicit Counter(void (*fn)(sigval_t)) : value(0), timer_valid(false) {
+  explicit Counter(void (*fn)(sigval)) : value(0), timer_valid(false) {
     memset(&se, 0, sizeof(se));
     se.sigev_notify = SIGEV_THREAD;
     se.sigev_notify_function = fn;
@@ -575,12 +579,12 @@
     return current_value != value;
   }
 
-  static void CountNotifyFunction(sigval_t value) {
+  static void CountNotifyFunction(sigval value) {
     Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
     ++cd->value;
   }
 
-  static void CountAndDisarmNotifyFunction(sigval_t value) {
+  static void CountAndDisarmNotifyFunction(sigval value) {
     Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
     ++cd->value;
 
@@ -644,7 +648,7 @@
   ASSERT_EQ(EINVAL, errno);
 
   // A SIGEV_THREAD timer is more interesting because we have stuff to clean up.
-  sigevent_t se;
+  sigevent se;
   memset(&se, 0, sizeof(se));
   se.sigev_notify = SIGEV_THREAD;
   se.sigev_notify_function = NoOpNotifyFunction;
@@ -715,7 +719,7 @@
   volatile bool complete;
 };
 
-static void TimerDeleteCallback(sigval_t value) {
+static void TimerDeleteCallback(sigval value) {
   TimerDeleteData* tdd = reinterpret_cast<TimerDeleteData*>(value.sival_ptr);
 
   tdd->tid = gettid();
@@ -725,7 +729,7 @@
 
 TEST(time, timer_delete_from_timer_thread) {
   TimerDeleteData tdd;
-  sigevent_t se;
+  sigevent se;
 
   memset(&se, 0, sizeof(se));
   se.sigev_notify = SIGEV_THREAD;
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 7d1e612..6e495fc 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -183,7 +183,7 @@
   ASSERT_EQ(123, sb.st_size);
 }
 
-TEST(UNISTD_TEST, truncate64) {
+TEST(UNISTD_TEST, truncate64_smoke) {
   TemporaryFile tf;
   ASSERT_EQ(0, close(tf.fd));
   ASSERT_EQ(0, truncate64(tf.path, 123));
@@ -203,7 +203,7 @@
   ASSERT_EQ(123, sb.st_size);
 }
 
-TEST(UNISTD_TEST, ftruncate64) {
+TEST(UNISTD_TEST, ftruncate64_smoke) {
   TemporaryFile tf;
   ASSERT_EQ(0, ftruncate64(tf.fd, 123));
   ASSERT_EQ(0, close(tf.fd));
@@ -739,7 +739,7 @@
   // Does uname(2) agree?
   utsname buf;
   ASSERT_EQ(0, uname(&buf));
-  ASSERT_EQ(0, strncmp(hostname, buf.nodename, SYS_NMLN));
+  ASSERT_EQ(0, strncmp(hostname, buf.nodename, sizeof(buf.nodename)));
   ASSERT_GT(strlen(hostname), 0U);
 
   // Do we correctly detect truncation?
@@ -852,7 +852,9 @@
   EXPECT_EQ(_POSIX_VERSION, _POSIX_MONOTONIC_CLOCK);
 #endif
   EXPECT_GT(_POSIX_NO_TRUNC, 0);
+#if !defined(MUSL)
   EXPECT_EQ(_POSIX_VERSION, _POSIX_PRIORITY_SCHEDULING);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_RAW_SOCKETS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_READER_WRITER_LOCKS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_REALTIME_SIGNALS);
@@ -861,8 +863,10 @@
   EXPECT_EQ(_POSIX_VERSION, _POSIX_SEMAPHORES);
   EXPECT_GT(_POSIX_SHELL, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_SPAWN);
+#if !defined(MUSL)
   EXPECT_EQ(-1, _POSIX_SPORADIC_SERVER);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_SYNCHRONIZED_IO);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREADS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKADDR);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKSIZE);
@@ -871,27 +875,37 @@
 #endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIORITY_SCHEDULING);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PROCESS_SHARED);
+#if !defined(MUSL)
   EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_PROTECT);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_SAFE_FUNCTIONS);
+#if !defined(MUSL)
   EXPECT_EQ(-1, _POSIX_THREAD_SPORADIC_SERVER);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMEOUTS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMERS);
+#if !defined(MUSL)
   EXPECT_EQ(-1, _POSIX_TRACE);
   EXPECT_EQ(-1, _POSIX_TRACE_EVENT_FILTER);
   EXPECT_EQ(-1, _POSIX_TRACE_INHERIT);
   EXPECT_EQ(-1, _POSIX_TRACE_LOG);
   EXPECT_EQ(-1, _POSIX_TYPED_MEMORY_OBJECTS);
+#endif
   EXPECT_NE(-1, _POSIX_VDISABLE);
 
   EXPECT_EQ(_POSIX_VERSION, _POSIX2_VERSION);
   EXPECT_EQ(_POSIX_VERSION, _POSIX2_C_BIND);
+#if !defined(MUSL)
   EXPECT_EQ(_POSIX_VERSION, _POSIX2_CHAR_TERM);
+#endif
 
   EXPECT_EQ(700, _XOPEN_VERSION);
   EXPECT_EQ(1, _XOPEN_ENH_I18N);
+#if !defined(MUSL)
   EXPECT_EQ(1, _XOPEN_REALTIME);
   EXPECT_EQ(1, _XOPEN_REALTIME_THREADS);
   EXPECT_EQ(1, _XOPEN_SHM);
+#endif
   EXPECT_EQ(1, _XOPEN_UNIX);
 
 #if defined(__BIONIC__)
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index d0b5a4a..218c724 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -800,8 +800,12 @@
 }
 
 TEST(wchar, wmempcpy) {
+#if !defined(MUSL)
   wchar_t dst[6];
   ASSERT_EQ(&dst[4], wmempcpy(dst, L"hello", 4));
+#else
+  GTEST_SKIP() << "musl doesn't have wmempcpy";
+#endif
 }
 
 template <typename T>
@@ -913,15 +917,27 @@
 }
 
 TEST(wchar, wcstod_l) {
+#if !defined(MUSL)
   EXPECT_EQ(1.23, wcstod_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+#else
+  GTEST_SKIP() << "musl doesn't have wcstod_l";
+#endif
 }
 
 TEST(wchar, wcstof_l) {
+#if !defined(MUSL)
   EXPECT_EQ(1.23f, wcstof_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+#else
+  GTEST_SKIP() << "musl doesn't have wcstof_l";
+#endif
 }
 
 TEST(wchar, wcstol_l) {
+#if !defined(MUSL)
   EXPECT_EQ(123L, wcstol_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+#else
+  GTEST_SKIP() << "musl doesn't have wcstol_l";
+#endif
 }
 
 TEST(wchar, wcstold_l) {
@@ -933,11 +949,15 @@
 }
 
 TEST(wchar, wcstoul_l) {
+#if !defined(MUSL)
   EXPECT_EQ(123UL, wcstoul_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+#else
+  GTEST_SKIP() << "musl doesn't have wcstoul_l";
+#endif
 }
 
 TEST(wchar, wcstoull_l) {
-  EXPECT_EQ(123ULL, wcstoul_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(123ULL, wcstoull_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
 }
 
 static void AssertWcwidthRange(wchar_t begin, wchar_t end, int expected) {