Snap for 8570526 from 2b9f1ae9aed225b81ee6864d8c65df00d9c8cd15 to mainline-networking-release

Change-Id: I9f7b6b7e0a2d0fcc703b35bf1b89f3c13bc3c366
diff --git a/Android.bp b/Android.bp
index 461f1db..ef56692 100644
--- a/Android.bp
+++ b/Android.bp
@@ -57,6 +57,9 @@
     native_bridge_supported: true,
     export_include_dirs: ["include"],
 
+    header_libs: ["fmtlib_headers"],
+    export_header_lib_headers: ["fmtlib_headers"],
+
     target: {
         linux_bionic: {
             enabled: true,
@@ -80,10 +83,12 @@
         "chrono_utils.cpp",
         "cmsg.cpp",
         "file.cpp",
+        "hex.cpp",
         "logging.cpp",
         "mapped_file.cpp",
         "parsebool.cpp",
         "parsenetaddress.cpp",
+        "posix_strerror_r.cpp",
         "process.cpp",
         "properties.cpp",
         "stringprintf.cpp",
@@ -146,7 +151,6 @@
         "libbase_headers",
     ],
     export_header_lib_headers: ["libbase_headers"],
-    static_libs: ["fmtlib"],
     whole_static_libs: ["fmtlib"],
     export_static_lib_headers: ["fmtlib"],
     apex_available: [
@@ -161,9 +165,7 @@
     sdk_version: "current",
     stl: "c++_static",
     export_include_dirs: ["include"],
-    static_libs: ["fmtlib_ndk"],
     whole_static_libs: ["fmtlib_ndk"],
-    export_static_lib_headers: ["fmtlib_ndk"],
 }
 
 // Tests
@@ -180,6 +182,7 @@
         "expected_test.cpp",
         "file_test.cpp",
         "function_ref_test.cpp",
+        "hex_test.cpp",
         "logging_splitters_test.cpp",
         "logging_test.cpp",
         "macros_test.cpp",
@@ -215,6 +218,7 @@
     },
     local_include_dirs: ["."],
     shared_libs: ["libbase"],
+    static_libs: ["libgmock"],
     compile_multilib: "both",
     multilib: {
         lib32: {
@@ -244,6 +248,37 @@
     test_suites: ["device_tests"],
 }
 
+// Can be removed when we move to c++20
+cc_test {
+    name: "libbase_result_constraint_test",
+    defaults: ["libbase_cflags_defaults"],
+    host_supported: true,
+    srcs: [
+        "result_test_constraint.cpp",
+    ],
+    target: {
+        android: {
+            sanitize: {
+                misc_undefined: ["integer"],
+            },
+        },
+    },
+    cpp_std: "gnu++20",
+    local_include_dirs: ["."],
+    shared_libs: ["libbase"],
+    static_libs: ["libgmock"],
+    compile_multilib: "both",
+    multilib: {
+        lib32: {
+            suffix: "32",
+        },
+        lib64: {
+            suffix: "64",
+        },
+    },
+    test_suites: ["device-tests"],
+}
+
 cc_benchmark {
     name: "libbase_benchmark",
     defaults: ["libbase_cflags_defaults"],
diff --git a/OWNERS b/OWNERS
index 97777f7..682a067 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1 @@
 enh@google.com
-jmgao@google.com
-tomcherry@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 3659bee..a3b2bfc 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -3,5 +3,10 @@
     {
       "name": "libbase_test"
     }
+  ],
+  "hwasan-postsubmit": [
+    {
+      "name": "libbase_test"
+    }
   ]
 }
diff --git a/hex.cpp b/hex.cpp
new file mode 100644
index 0000000..a4b7715
--- /dev/null
+++ b/hex.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android-base/hex.h"
+
+#include "android-base/logging.h"
+
+namespace android {
+namespace base {
+
+std::string HexString(const void* bytes, size_t len) {
+  CHECK(bytes != nullptr || len == 0) << bytes << " " << len;
+
+  // b/132916539: Doing this the 'C way', std::setfill triggers ubsan implicit conversion
+  const uint8_t* bytes8 = static_cast<const uint8_t*>(bytes);
+  const char chars[] = "0123456789abcdef";
+  std::string result;
+  result.resize(len * 2);
+
+  for (size_t i = 0; i < len; i++) {
+    result[2 * i] = chars[bytes8[i] >> 4];
+    result[2 * i + 1] = chars[bytes8[i] & 0xf];
+  }
+
+  return result;
+}
+
+}  // namespace base
+}  // namespace android
diff --git a/hex_test.cpp b/hex_test.cpp
new file mode 100644
index 0000000..ebf798c
--- /dev/null
+++ b/hex_test.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android-base/hex.h"
+
+#include <gtest/gtest.h>
+
+TEST(hex, empty) {
+  ASSERT_EQ("", android::base::HexString(nullptr, 0));
+  ASSERT_EQ("", android::base::HexString(reinterpret_cast<void*>(int32_t(0)), 0));
+}
+
+TEST(hex, short) {
+  const int32_t kShortData = 0xDEADBEEF;
+  ASSERT_EQ("ef", android::base::HexString(&kShortData, 1));
+  ASSERT_EQ("efbe", android::base::HexString(&kShortData, 2));
+  ASSERT_EQ("efbead", android::base::HexString(&kShortData, 3));
+  ASSERT_EQ("efbeadde", android::base::HexString(&kShortData, 4));
+}
+
+TEST(hex, all) {
+  constexpr size_t kSize = 256;
+  uint8_t kLongData[kSize];
+  for (size_t i = 0; i < kSize; i++) {
+    kLongData[i] = i;
+  }
+
+  ASSERT_EQ(
+      "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d"
+      "2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b"
+      "5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586878889"
+      "8a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7"
+      "b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5"
+      "e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+      android::base::HexString(&kLongData, kSize));
+}
diff --git a/include/android-base/endian.h b/include/android-base/endian.h
index 8fa6365..b47494b 100644
--- a/include/android-base/endian.h
+++ b/include/android-base/endian.h
@@ -25,18 +25,19 @@
 
 #include <sys/endian.h>
 
-#elif defined(__GLIBC__)
+#elif defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
 
-/* glibc's <endian.h> is like bionic's <sys/endian.h>. */
+/* glibc and musl's <endian.h> are like bionic's <sys/endian.h>. */
 #include <endian.h>
 
-/* glibc keeps htons and htonl in <netinet/in.h>. */
+/* glibc and musl keep htons and htonl in <netinet/in.h>. */
 #include <netinet/in.h>
 
-/* glibc doesn't have the 64-bit variants. */
+/* glibc and musl don't have the 64-bit variants. */
 #define htonq(x) htobe64(x)
 #define ntohq(x) be64toh(x)
 
+#if defined(__GLIBC__)
 /* glibc has different names to BSD for these. */
 #define betoh16(x) be16toh(x)
 #define betoh32(x) be32toh(x)
@@ -44,6 +45,7 @@
 #define letoh16(x) le16toh(x)
 #define letoh32(x) le32toh(x)
 #define letoh64(x) le64toh(x)
+#endif
 
 #else
 
diff --git a/include/android-base/errors.h b/include/android-base/errors.h
index 06f29fc..61fdbd8 100644
--- a/include/android-base/errors.h
+++ b/include/android-base/errors.h
@@ -29,6 +29,8 @@
 
 #pragma once
 
+#include <assert.h>
+
 #include <string>
 
 namespace android {
@@ -41,3 +43,102 @@
 
 }  // namespace base
 }  // namespace android
+
+// Convenient macros for evaluating a statement, checking if the result is error, and returning it
+// to the caller.
+//
+// Usage with Result<T>:
+//
+// Result<Foo> getFoo() {...}
+//
+// Result<Bar> getBar() {
+//   Foo foo = OR_RETURN(getFoo());
+//   return Bar{foo};
+// }
+//
+// Usage with status_t:
+//
+// status_t getFoo(Foo*) {...}
+//
+// status_t getBar(Bar* bar) {
+//   Foo foo;
+//   OR_RETURN(getFoo(&foo));
+//   *bar = Bar{foo};
+//   return OK;
+// }
+//
+// Actually this can be used for any type as long as the OkOrFail<T> contract is satisfied. See
+// below.
+// If implicit conversion compilation errors occur involving a value type with a templated
+// forwarding ref ctor, compilation with cpp20 or explicitly converting to the desired
+// return type is required.
+#define OR_RETURN(expr)                                                                 \
+  ({                                                                                    \
+    decltype(expr)&& tmp = (expr);                                                      \
+    typedef android::base::OkOrFail<std::remove_reference_t<decltype(tmp)>> ok_or_fail; \
+    if (!ok_or_fail::IsOk(tmp)) {                                                       \
+      return ok_or_fail::Fail(std::move(tmp));                                          \
+    }                                                                                   \
+    ok_or_fail::Unwrap(std::move(tmp));                                                 \
+  })
+
+// Same as OR_RETURN, but aborts if expr is a failure.
+#if defined(__BIONIC__)
+#define OR_FATAL(expr)                                                                  \
+  ({                                                                                    \
+    decltype(expr)&& tmp = (expr);                                                      \
+    typedef android::base::OkOrFail<std::remove_reference_t<decltype(tmp)>> ok_or_fail; \
+    if (!ok_or_fail::IsOk(tmp)) {                                                       \
+      __assert(__FILE__, __LINE__, ok_or_fail::ErrorMessage(tmp).c_str());              \
+    }                                                                                   \
+    ok_or_fail::Unwrap(std::move(tmp));                                                 \
+  })
+#else
+#define OR_FATAL(expr)                                                                  \
+  ({                                                                                    \
+    decltype(expr)&& tmp = (expr);                                                      \
+    typedef android::base::OkOrFail<std::remove_reference_t<decltype(tmp)>> ok_or_fail; \
+    if (!ok_or_fail::IsOk(tmp)) {                                                       \
+      fprintf(stderr, "%s:%d: assertion \"%s\" failed", __FILE__, __LINE__,             \
+              ok_or_fail::ErrorMessage(tmp).c_str());                                   \
+      abort();                                                                          \
+    }                                                                                   \
+    ok_or_fail::Unwrap(std::move(tmp));                                                 \
+  })
+#endif
+
+namespace android {
+namespace base {
+
+// The OkOrFail contract for a type T. This must be implemented for a type T if you want to use
+// OR_RETURN(stmt) where stmt evalues to a value of type T.
+template <typename T, typename = void>
+struct OkOrFail {
+  // Checks if T is ok or fail.
+  static bool IsOk(const T&);
+
+  // Turns T into the success value.
+  template <typename U>
+  static U Unwrap(T&&);
+
+  // Moves T into OkOrFail<T>, so that we can convert it to other types
+  OkOrFail(T&& v);
+  OkOrFail() = delete;
+  OkOrFail(const T&) = delete;
+
+  // And there need to be one or more conversion operators that turns the error value of T into a
+  // target type. For example, for T = Result<V, E>, there can be ...
+  //
+  // // for the case where OR_RETURN is called in a function expecting E
+  // operator E()&& { return val_.error().code(); }
+  //
+  // // for the case where OR_RETURN is called in a function expecting Result<U, E>
+  // template <typename U>
+  // operator Result<U, E>()&& { return val_.error(); }
+
+  // Returns the string representation of the fail value.
+  static std::string ErrorMessage(const T& v);
+};
+
+}  // namespace base
+}  // namespace android
diff --git a/include/android-base/expected.h b/include/android-base/expected.h
index 11cf1ac..3b9d45f 100644
--- a/include/android-base/expected.h
+++ b/include/android-base/expected.h
@@ -37,7 +37,7 @@
 //
 // void test() {
 //   auto q = safe_divide(10, 0);
-//   if (q) { printf("%f\n", q.value()); }
+//   if (q.ok()) { printf("%f\n", q.value()); }
 //   else { printf("%s\n", q.error().c_str()); }
 // }
 //
diff --git a/include/android-base/hex.h b/include/android-base/hex.h
new file mode 100644
index 0000000..cbb26a8
--- /dev/null
+++ b/include/android-base/hex.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+
+namespace android {
+namespace base {
+
+// Converts binary data into a hexString.
+//
+// Hex values are printed in order, e.g. 0xDEAD will result in 'adde' because
+// Android is little-endian.
+std::string HexString(const void* bytes, size_t len);
+
+}  // namespace base
+}  // namespace android
diff --git a/include/android-base/result-gmock.h b/include/android-base/result-gmock.h
new file mode 100644
index 0000000..1fd9f00
--- /dev/null
+++ b/include/android-base/result-gmock.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include <android-base/result.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+/*
+ * Matchers for android::base::Result<T> that produces human-readable test results.
+ *
+ * Example:
+ *
+ * Result<int> result = ...
+ *
+ * using namespace ::android::base::testing;
+ * using namespace ::testing;
+ *
+ * EXPECT_THAT(result, Ok());
+ * EXPECT_THAT(result, Not(Ok()));
+ * EXPECT_THAT(result, HasValue(5));
+ * EXPECT_THAT(result, HasError(WithCode(EBADF)));
+ * EXPECT_THAT(result, HasError(WithMessageMessage("expected error message")));
+ *
+ * // Advance usage
+ * EXPECT_THAT(result, AnyOf(Ok(), HasError(WithCode(EACCES)));
+ * EXPECT_THAT(result, HasError(WithCode(AnyOf(EBADF, EACCES))) << "Unexpected code from library";
+ */
+
+namespace android::base {
+
+template <typename T>
+inline void PrintTo(const Result<T>& result, std::ostream* os) {
+  if (result.ok()) {
+    *os << "OK: " << ::testing::PrintToString(result.value());
+  } else {
+    *os << "Error: " << result.error();
+  }
+}
+
+template <>
+inline void PrintTo(const Result<void>& result, std::ostream* os) {
+  if (result.ok()) {
+    *os << "OK";
+  } else {
+    *os << "Error: " << result.error();
+  }
+}
+
+namespace testing {
+
+MATCHER(Ok, "") {
+  if (arg.ok()) {
+    *result_listener << "result is OK";
+    return true;
+  }
+  *result_listener << "error is " << arg.error();
+  return false;
+}
+
+MATCHER_P(HasValue, value_matcher, "") {
+  if (arg.ok()) {
+    return ::testing::ExplainMatchResult(value_matcher, arg.value(), result_listener);
+  }
+  *result_listener << "error is " << arg.error();
+  return false;
+}
+
+MATCHER_P(HasError, error_matcher, "") {
+  if (!arg.ok()) {
+    return ::testing::ExplainMatchResult(error_matcher, arg.error(), result_listener);
+  }
+  *result_listener << "result is OK";
+  return false;
+}
+
+MATCHER_P(WithCode, code_matcher, "") {
+  *result_listener << "actual error is " << arg;
+  return ::testing::ExplainMatchResult(code_matcher, arg.code(), result_listener);
+}
+
+MATCHER_P(WithMessage, message_matcher, "") {
+  *result_listener << "actual error is " << arg;
+  return ::testing::ExplainMatchResult(message_matcher, arg.message(), result_listener);
+}
+
+}  // namespace testing
+}  // namespace android::base
diff --git a/include/android-base/result.h b/include/android-base/result.h
index 56a4f3e..9715a8c 100644
--- a/include/android-base/result.h
+++ b/include/android-base/result.h
@@ -14,125 +14,212 @@
  * limitations under the License.
  */
 
-// This file contains classes for returning a successful result along with an optional
-// arbitrarily typed return value or for returning a failure result along with an optional string
-// indicating why the function failed.
-
-// There are 3 classes that implement this functionality and one additional helper type.
+// Result<T, E> is the type that is used to pass a success value of type T or an error code of type
+// E, optionally together with an error message. T and E can be any type. If E is omitted it
+// defaults to int, which is useful when errno(3) is used as the error code.
 //
-// Result<T> either contains a member of type T that can be accessed using similar semantics as
-// std::optional<T> or it contains a ResultError describing an error, which can be accessed via
-// Result<T>::error().
+// Passing a success value or an error value:
 //
-// ResultError is a type that contains both a std::string describing the error and a copy of errno
-// from when the error occurred.  ResultError can be used in an ostream directly to print its
-// string value.
-//
-// Result<void> is the correct return type for a function that either returns successfully or
-// returns an error value.  Returning {} from a function that returns Result<void> is the
-// correct way to indicate that a function without a return type has completed successfully.
-//
-// A successful Result<T> is constructed implicitly from any type that can be implicitly converted
-// to T or from the constructor arguments for T.  This allows you to return a type T directly from
-// a function that returns Result<T>.
-//
-// Error and ErrnoError are used to construct a Result<T> that has failed.  The Error class takes
-// an ostream as an input and are implicitly cast to a Result<T> containing that failure.
-// ErrnoError() is a helper function to create an Error class that appends ": " + strerror(errno)
-// to the end of the failure string to aid in interacting with C APIs.  Alternatively, an errno
-// value can be directly specified via the Error() constructor.
-//
-// Errorf and ErrnoErrorf accept the format string syntax of the fmblib (https://fmt.dev).
-// Errorf("{} errors", num) is equivalent to Error() << num << " errors".
-//
-// ResultError can be used in the ostream and when using Error/Errorf to construct a Result<T>.
-// In this case, the string that the ResultError takes is passed through the stream normally, but
-// the errno is passed to the Result<T>. This can be used to pass errno from a failing C function up
-// multiple callers. Note that when the outer Result<T> is created with ErrnoError/ErrnoErrorf then
-// the errno from the inner ResultError is not passed. Also when multiple ResultError objects are
-// used, the errno of the last one is respected.
-//
-// ResultError can also directly construct a Result<T>.  This is particularly useful if you have a
-// function that return Result<T> but you have a Result<U> and want to return its error.  In this
-// case, you can return the .error() from the Result<U> to construct the Result<T>.
-
-// An example of how to use these is below:
-// Result<U> CalculateResult(const T& input) {
-//   U output;
-//   if (!SomeOtherCppFunction(input, &output)) {
-//     return Errorf("SomeOtherCppFunction {} failed", input);
+// Result<std::string> readFile() {
+//   std::string content;
+//   if (base::ReadFileToString("path", &content)) {
+//     return content; // ok case
+//   } else {
+//     return ErrnoError() << "failed to read"; // error case
 //   }
-//   if (!c_api_function(output)) {
-//     return ErrnoErrorf("c_api_function {} failed", output);
-//   }
-//   return output;
 // }
 //
-// auto output = CalculateResult(input);
-// if (!output) return Error() << "CalculateResult failed: " << output.error();
-// UseOutput(*output);
+// Checking the result and then unwrapping the value or propagating the error:
+//
+// Result<bool> hasAWord() {
+//   auto content = readFile();
+//   if (!content.ok()) {
+//     return Error() << "failed to process: " << content.error();
+//   }
+//   return (*content.find("happy") != std::string::npos);
+// }
+//
+// Using custom error code type:
+//
+// enum class MyError { A, B }; // assume that this is the error code you already have
+//
+// // To use the error code with Result, define a wrapper class that provides the following
+// operations and use the wrapper class as the second type parameter (E) when instantiating
+// Result<T, E>
+//
+// 1. default constructor
+// 2. copy constructor / and move constructor if copying is expensive
+// 3. conversion operator to the error code type
+// 4. value() function that return the error code value
+// 5. print() function that gives a string representation of the error ode value
+//
+// struct MyErrorWrapper {
+//   MyError val_;
+//   MyErrorWrapper() : val_(/* reasonable default value */) {}
+//   MyErrorWrapper(MyError&& e) : val_(std:forward<MyError>(e)) {}
+//   operator const MyError&() const { return val_; }
+//   MyError value() const { return val_; }
+//   std::string print() const {
+//     switch(val_) {
+//       MyError::A: return "A";
+//       MyError::B: return "B";
+//     }
+//   }
+// };
+//
+// #define NewMyError(e) Error<MyErrorWrapper>(MyError::e)
+//
+// Result<T, MyError> val = NewMyError(A) << "some message";
+//
+// Formatting the error message using fmtlib:
+//
+// Errorf("{} errors", num); // equivalent to Error() << num << " errors";
+// ErrnoErrorf("{} errors", num); // equivalent to ErrnoError() << num << " errors";
+//
+// Returning success or failure, but not the value:
+//
+// Result<void> doSomething() {
+//   if (success) return {};
+//   else return Error() << "error occurred";
+// }
+//
+// Extracting error code:
+//
+// Result<T> val = Error(3) << "some error occurred";
+// assert(3 == val.error().code());
+//
 
 #pragma once
 
+#include <assert.h>
 #include <errno.h>
 
 #include <sstream>
 #include <string>
+#include <type_traits>
 
+#include "android-base/errors.h"
 #include "android-base/expected.h"
 #include "android-base/format.h"
 
 namespace android {
 namespace base {
 
+// Errno is a wrapper class for errno(3). Use this type instead of `int` when instantiating
+// `Result<T, E>` and `Error<E>` template classes. This is required to distinguish errno from other
+// integer-based error code types like `status_t`.
+struct Errno {
+  Errno() : val_(0) {}
+  Errno(int e) : val_(e) {}
+  int value() const { return val_; }
+  operator int() const { return value(); }
+  std::string print() const { return strerror(value()); }
+
+  int val_;
+
+  // TODO(b/209929099): remove this conversion operator. This currently is needed to not break
+  // existing places where error().code() is used to construct enum values.
+  template <typename E, typename = std::enable_if_t<std::is_enum_v<E>>>
+  operator E() const {
+    return E(val_);
+  }
+};
+
+template <typename E = Errno, bool include_message = true>
 struct ResultError {
-  template <typename T>
-  ResultError(T&& message, int code) : message_(std::forward<T>(message)), code_(code) {}
+  template <typename T, typename P, typename = std::enable_if_t<std::is_convertible_v<P, E>>>
+  ResultError(T&& message, P&& code)
+      : message_(std::forward<T>(message)), code_(E(std::forward<P>(code))) {}
 
   template <typename T>
   // NOLINTNEXTLINE(google-explicit-constructor)
-  operator android::base::expected<T, ResultError>() {
-    return android::base::unexpected(ResultError(message_, code_));
+  operator android::base::expected<T, ResultError<E>>() const {
+    return android::base::unexpected(ResultError<E>(message_, code_));
   }
 
   std::string message() const { return message_; }
-  int code() const { return code_; }
+  const E& code() const { return code_; }
 
  private:
   std::string message_;
-  int code_;
+  E code_;
 };
 
-inline bool operator==(const ResultError& lhs, const ResultError& rhs) {
+template <typename E>
+struct ResultError<E, /* include_message */ false> {
+  template <typename P, typename = std::enable_if_t<std::is_convertible_v<P, E>>>
+  ResultError(P&& code) : code_(E(std::forward<P>(code))) {}
+
+  template <typename T>
+  operator android::base::expected<T, ResultError<E, false>>() const {
+    return android::base::unexpected(ResultError<E, false>(code_));
+  }
+
+  const E& code() const { return code_; }
+
+ private:
+  E code_;
+};
+
+template <typename E>
+inline bool operator==(const ResultError<E>& lhs, const ResultError<E>& rhs) {
   return lhs.message() == rhs.message() && lhs.code() == rhs.code();
 }
 
-inline bool operator!=(const ResultError& lhs, const ResultError& rhs) {
+template <typename E>
+inline bool operator!=(const ResultError<E>& lhs, const ResultError<E>& rhs) {
   return !(lhs == rhs);
 }
 
-inline std::ostream& operator<<(std::ostream& os, const ResultError& t) {
+template <typename E>
+inline std::ostream& operator<<(std::ostream& os, const ResultError<E>& t) {
   os << t.message();
   return os;
 }
 
+namespace internal {
+// Stream class that does nothing and is has zero (actually 1) size. It is used instead of
+// std::stringstream when include_message is false so that we use less on stack.
+// sizeof(std::stringstream) is 280 on arm64.
+struct DoNothingStream {
+  template <typename T>
+  DoNothingStream& operator<<(T&&) {
+    return *this;
+  }
+
+  std::string str() const { return ""; }
+};
+}  // namespace internal
+
+template <typename E = Errno, bool include_message = true,
+          typename = std::enable_if_t<!std::is_same_v<E, int>>>
 class Error {
  public:
-  Error() : errno_(0), append_errno_(false) {}
+  Error() : code_(0), has_code_(false) {}
+  template <typename P, typename = std::enable_if_t<std::is_convertible_v<P, E>>>
   // NOLINTNEXTLINE(google-explicit-constructor)
-  Error(int errno_to_append) : errno_(errno_to_append), append_errno_(true) {}
+  Error(P&& code) : code_(std::forward<P>(code)), has_code_(true) {}
 
-  template <typename T>
+  template <typename T, typename P, typename = std::enable_if_t<std::is_convertible_v<E, P>>>
   // NOLINTNEXTLINE(google-explicit-constructor)
-  operator android::base::expected<T, ResultError>() {
-    return android::base::unexpected(ResultError(str(), errno_));
+  operator android::base::expected<T, ResultError<P>>() const {
+    return android::base::unexpected(ResultError<P>(str(), static_cast<P>(code_)));
+  }
+
+  template <typename T, typename P, typename = std::enable_if_t<std::is_convertible_v<E, P>>>
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  operator android::base::expected<T, ResultError<P, false>>() const {
+    return android::base::unexpected(ResultError<P, false>(static_cast<P>(code_)));
   }
 
   template <typename T>
   Error& operator<<(T&& t) {
+    static_assert(include_message, "<< not supported when include_message = false");
     // NOLINTNEXTLINE(bugprone-suspicious-semicolon)
-    if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, ResultError>) {
-      errno_ = t.code();
+    if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, ResultError<E>>) {
+      if (!has_code_) {
+        code_ = t.code();
+      }
       return (*this) << t.message();
     }
     int saved = errno;
@@ -142,12 +229,13 @@
   }
 
   const std::string str() const {
+    static_assert(include_message, "str() not supported when include_message = false");
     std::string str = ss_.str();
-    if (append_errno_) {
+    if (has_code_) {
       if (str.empty()) {
-        return strerror(errno_);
+        return code_.print();
       }
-      return std::move(str) + ": " + strerror(errno_);
+      return std::move(str) + ": " + code_.print();
     }
     return str;
   }
@@ -164,72 +252,183 @@
   friend Error ErrnoErrorfImpl(const T&& fmt, const Args&... args);
 
  private:
-  Error(bool append_errno, int errno_to_append, const std::string& message)
-      : errno_(errno_to_append), append_errno_(append_errno) {
+  Error(bool has_code, E code, const std::string& message) : code_(code), has_code_(has_code) {
     (*this) << message;
   }
 
-  std::stringstream ss_;
-  int errno_;
-  const bool append_errno_;
+  std::conditional_t<include_message, std::stringstream, internal::DoNothingStream> ss_;
+  E code_;
+  const bool has_code_;
 };
 
-inline Error ErrnoError() {
-  return Error(errno);
+inline Error<Errno> ErrnoError() {
+  return Error<Errno>(Errno{errno});
 }
 
-inline int ErrorCode(int code) {
+template <typename E>
+inline E ErrorCode(E code) {
   return code;
 }
 
 // Return the error code of the last ResultError object, if any.
 // Otherwise, return `code` as it is.
-template <typename T, typename... Args>
-inline int ErrorCode(int code, T&& t, const Args&... args) {
-  if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, ResultError>) {
+template <typename T, typename E, typename... Args>
+inline E ErrorCode(E code, T&& t, const Args&... args) {
+  if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, ResultError<E>>) {
     return ErrorCode(t.code(), args...);
   }
   return ErrorCode(code, args...);
 }
 
 template <typename T, typename... Args>
-inline Error ErrorfImpl(const T&& fmt, const Args&... args) {
-  return Error(false, ErrorCode(0, args...), fmt::format(fmt, args...));
+inline Error<Errno> ErrorfImpl(const T&& fmt, const Args&... args) {
+  return Error(false, ErrorCode(Errno{}, args...), fmt::format(fmt, args...));
 }
 
 template <typename T, typename... Args>
-inline Error ErrnoErrorfImpl(const T&& fmt, const Args&... args) {
-  return Error(true, errno, fmt::format(fmt, args...));
+inline Error<Errno> ErrnoErrorfImpl(const T&& fmt, const Args&... args) {
+  return Error<Errno>(true, Errno{errno}, fmt::format(fmt, args...));
 }
 
 #define Errorf(fmt, ...) android::base::ErrorfImpl(FMT_STRING(fmt), ##__VA_ARGS__)
 #define ErrnoErrorf(fmt, ...) android::base::ErrnoErrorfImpl(FMT_STRING(fmt), ##__VA_ARGS__)
 
+template <typename T, typename E = Errno, bool include_message = true>
+using Result = android::base::expected<T, ResultError<E, include_message>>;
+
+// Specialization of android::base::OkOrFail<V> for V = Result<T, E>. See android-base/errors.h
+// for the contract.
+
+namespace impl {
+template <typename U>
+using Code = std::decay_t<decltype(std::declval<U>().error().code())>;
+
+template <typename U>
+using ErrorType = std::decay_t<decltype(std::declval<U>().error())>;
+
+template <typename U>
+constexpr bool IsNumeric = std::is_integral_v<U> || std::is_floating_point_v<U> ||
+                           (std::is_enum_v<U> && std::is_convertible_v<U, size_t>);
+
+// This base class exists to take advantage of shadowing
+// We include the conversion in this base class so that if the conversion in NumericConversions
+// overlaps, we (arbitrarily) choose the implementation in NumericConversions due to shadowing.
 template <typename T>
-using Result = android::base::expected<T, ResultError>;
+struct ConversionBase {
+  ErrorType<T> error_;
+  // T is a expected<U, ErrorType<T>>.
+  operator const T() const && {
+    return unexpected(std::move(error_));
+  }
+
+  operator const Code<T>() const && {
+    return error_.code();
+  }
+
+};
+
+// User defined conversions can be followed by numeric conversions
+// Although we template specialize for the exact code type, we need
+// specializations for conversions to all numeric types to avoid an
+// ambiguous conversion sequence.
+template <typename T, typename = void>
+struct NumericConversions : public ConversionBase<T> {};
+template <typename T>
+struct NumericConversions<T,
+    std::enable_if_t<impl::IsNumeric<impl::Code<T>>>
+    > : public ConversionBase<T>
+{
+#pragma push_macro("SPECIALIZED_CONVERSION")
+#define SPECIALIZED_CONVERSION(type)\
+  operator const expected<type, ErrorType<T>>() const &&\
+  { return unexpected(std::move(this->error_));}
+
+  SPECIALIZED_CONVERSION(int)
+  SPECIALIZED_CONVERSION(short int)
+  SPECIALIZED_CONVERSION(unsigned short int)
+  SPECIALIZED_CONVERSION(unsigned int)
+  SPECIALIZED_CONVERSION(long int)
+  SPECIALIZED_CONVERSION(unsigned long int)
+  SPECIALIZED_CONVERSION(long long int)
+  SPECIALIZED_CONVERSION(unsigned long long int)
+  SPECIALIZED_CONVERSION(bool)
+  SPECIALIZED_CONVERSION(char)
+  SPECIALIZED_CONVERSION(unsigned char)
+  SPECIALIZED_CONVERSION(signed char)
+  SPECIALIZED_CONVERSION(wchar_t)
+  SPECIALIZED_CONVERSION(char16_t)
+  SPECIALIZED_CONVERSION(char32_t)
+  SPECIALIZED_CONVERSION(float)
+  SPECIALIZED_CONVERSION(double)
+  SPECIALIZED_CONVERSION(long double)
+
+#undef SPECIALIZED_CONVERSION
+#pragma pop_macro("SPECIALIZED_CONVERSION")
+  // For debugging purposes
+  using IsNumericT = std::true_type;
+};
+
+#ifdef __cpp_concepts
+template<class U>
+concept Trivial = std::is_same_v<U, U>;
+#endif
+} // namespace impl
+
+template <typename T, typename E, bool include_message>
+struct OkOrFail<Result<T, E, include_message>>
+    : public impl::NumericConversions<Result<T, E, include_message>> {
+  using V = Result<T, E, include_message>;
+  using Err = impl::ErrorType<V>;
+  using C = impl::Code<V>;
+private:
+   OkOrFail(Err&& v): impl::NumericConversions<V>{std::move(v)} {}
+   OkOrFail(const OkOrFail& other) = delete;
+   OkOrFail(const OkOrFail&& other) = delete;
+public:
+  // Checks if V is ok or fail
+  static bool IsOk(const V& val) { return val.ok(); }
+
+  // Turns V into a success value
+  static T Unwrap(V&& val) { return std::move(val.value()); }
+
+  // Consumes V when it's a fail value
+  static const OkOrFail<V> Fail(V&& v) {
+    assert(!IsOk(v));
+    return OkOrFail<V>{std::move(v.error())};
+  }
+
+  // We specialize as much as possible to avoid ambiguous conversion with
+  // templated expected ctor
+  operator const Result<C, E, include_message>() const && {
+    return unexpected(std::move(this->error_));
+  }
+#ifdef __cpp_concepts
+  template <impl::Trivial U>
+#else
+  template <typename U>
+#endif
+  operator const Result<U, E, include_message>() const && {
+    return unexpected(std::move(this->error_));
+  }
+
+  static std::string ErrorMessage(const V& val) { return val.error().message(); }
+};
 
 // Macros for testing the results of functions that return android::base::Result.
 // These also work with base::android::expected.
+// For advanced matchers and customized error messages, see result-gtest.h.
 
-#define CHECK_RESULT_OK(stmt)       \
-  do {                              \
-    const auto& tmp = (stmt);       \
-    CHECK(tmp.ok()) << tmp.error(); \
-  } while (0)
+#define ASSERT_RESULT_OK(stmt)                            \
+  if (const auto& tmp = (stmt); !tmp.ok())                \
+  FAIL() << "Value of: " << #stmt << "\n"                 \
+         << "  Actual: " << tmp.error().message() << "\n" \
+         << "Expected: is ok\n"
 
-#define ASSERT_RESULT_OK(stmt)            \
-  do {                                    \
-    const auto& tmp = (stmt);             \
-    ASSERT_TRUE(tmp.ok()) << tmp.error(); \
-  } while (0)
-
-#define EXPECT_RESULT_OK(stmt)            \
-  do {                                    \
-    auto tmp = (stmt);                    \
-    EXPECT_TRUE(tmp.ok()) << tmp.error(); \
-  } while (0)
-
-// TODO: Maybe add RETURN_IF_ERROR() and ASSIGN_OR_RETURN()
+#define EXPECT_RESULT_OK(stmt)                                   \
+  if (const auto& tmp = (stmt); !tmp.ok())                       \
+  ADD_FAILURE() << "Value of: " << #stmt << "\n"                 \
+                << "  Actual: " << tmp.error().message() << "\n" \
+                << "Expected: is ok\n"
 
 }  // namespace base
 }  // namespace android
diff --git a/include/android-base/scopeguard.h b/include/android-base/scopeguard.h
index 5a224d6..8293b2c 100644
--- a/include/android-base/scopeguard.h
+++ b/include/android-base/scopeguard.h
@@ -26,14 +26,14 @@
 template <typename F>
 class ScopeGuard {
  public:
-  ScopeGuard(F&& f) : f_(std::forward<F>(f)), active_(true) {}
+  constexpr ScopeGuard(F&& f) : f_(std::forward<F>(f)), active_(true) {}
 
-  ScopeGuard(ScopeGuard&& that) noexcept : f_(std::move(that.f_)), active_(that.active_) {
+  constexpr ScopeGuard(ScopeGuard&& that) noexcept : f_(std::move(that.f_)), active_(that.active_) {
     that.active_ = false;
   }
 
   template <typename Functor>
-  ScopeGuard(ScopeGuard<Functor>&& that) : f_(std::move(that.f_)), active_(that.active_) {
+  constexpr ScopeGuard(ScopeGuard<Functor>&& that) : f_(std::move(that.f_)), active_(that.active_) {
     that.active_ = false;
   }
 
@@ -48,7 +48,7 @@
 
   void Disable() { active_ = false; }
 
-  bool active() const { return active_; }
+  constexpr bool active() const { return active_; }
 
  private:
   template <typename Functor>
diff --git a/include/android-base/silent_death_test.h b/include/android-base/silent_death_test.h
index 2aec890..261fa74 100644
--- a/include/android-base/silent_death_test.h
+++ b/include/android-base/silent_death_test.h
@@ -17,34 +17,113 @@
 #pragma once
 
 #include <signal.h>
-
 #include <gtest/gtest.h>
 
+#include <array>
+#include <memory>
+
 #if !defined(__BIONIC__)
 #define sigaction64 sigaction
 #endif
 
-// Disables debuggerd stack traces to speed up death tests and make them less
-// noisy in logcat.
+// INTRODUCTION
 //
-// Use `using my_DeathTest = SilentDeathTest;` instead of inheriting from
-// testing::Test yourself.
-class SilentDeathTest : public testing::Test {
- protected:
-  virtual void SetUp() {
-    // Suppress debuggerd stack traces. Too slow.
-    for (int signo : {SIGABRT, SIGBUS, SIGSEGV, SIGSYS}) {
+// It can be useful to disable debuggerd stack traces/tombstones in death tests.
+// Reasons include:
+//
+//   1. speeding up death tests
+//   2. reducing the noise in logcat (for humans)
+//   3. avoiding bots from thinking that expected deaths should be reported in
+//      stability metrics/have bugs auto-filed
+//
+// When writing new death tests, inherit the test suite from SilentDeathTest
+// defined below.
+//
+// Only use ScopedSilentDeath in a test case/suite if changing the test base
+// class from testing::Test to SilentDeathTest adds additional complextity when
+// test suite code is shared between death and non-death tests.
+//
+// EXAMPLES
+//
+// For example, use SilentDeathTest for this simple case where there's no shared
+// setup or teardown:
+//
+//   using FooDeathTest = SilentDeathTest;
+//
+//   TEST(FooTest, DoesThis) {
+//     // normal test
+//   }
+//
+//   TEST_F(FooDeathTest, DoesThat) {
+//     // death test
+//   }
+//
+// Alternatively, use ScopedSilentDeath if you already have a Test subclass for
+// shared setup or teardown:
+//
+//   class FooTest : public testing::Test { ... /* shared setup/teardown */ };
+//
+//   using FooDeathTest = FooTest;
+//
+//   TEST_F(FooTest, DoesThis) {
+//     // normal test
+//   }
+//
+//   TEST_F(FooDeathTest, DoesThat) {
+//     ScopedSilentDeath _silentDeath;
+//     // death test
+//   }
+//
+// NOTES
+//
+// When writing death tests, consider using ASSERT_EXIT() and EXPECT_EXIT()
+// rather than the more obvious ASSERT_DEATH()/EXPECT_DEATH() macros... The
+// advantage is that you can specify a regular expression that you expect
+// the abort message to match, and can be explicit about what signal you expect
+// to die with, and you can also test for *successful* exits too. Examples:
+//
+//   ASSERT_DEATH(foo(), "some text\\. some more\\.");
+//
+//   ASSERT_EXIT(bar(), testing::ExitedWithCode(0), "Success");
+//
+//   ASSERT_EXIT(baz(), testing::KilledBySignal(SIGABRT),
+//               "expected detail message \\(blah\\)");
+//
+// As you can see the regular expression functionality is there for
+// ASSERT_DEATH() too, but it's important to realize that it's a regular
+// expression, so (as in the first and third examples), you'll need to quote
+// any metacharacters (and because it's a string literal, you'll either need
+// extra quoting or want to use a raw string).
+
+class ScopedSilentDeath {
+ public:
+  ScopedSilentDeath() {
+    for (int signo : SUPPRESSED_SIGNALS) {
       struct sigaction64 action = {.sa_handler = SIG_DFL};
       sigaction64(signo, &action, &previous_);
     }
   }
 
-  virtual void TearDown() {
-    for (int signo : {SIGABRT, SIGBUS, SIGSEGV, SIGSYS}) {
+  ~ScopedSilentDeath() {
+    for (int signo : SUPPRESSED_SIGNALS) {
       sigaction64(signo, &previous_, nullptr);
     }
   }
 
  private:
+  static constexpr std::array<int, 4> SUPPRESSED_SIGNALS = {SIGABRT, SIGBUS, SIGSEGV, SIGSYS};
+
   struct sigaction64 previous_;
 };
+
+class SilentDeathTest : public testing::Test {
+ protected:
+  void SetUp() override {
+    silent_death_ = std::unique_ptr<ScopedSilentDeath>(new ScopedSilentDeath);
+  }
+
+  void TearDown() override { silent_death_.reset(); }
+
+ private:
+  std::unique_ptr<ScopedSilentDeath> silent_death_;
+};
diff --git a/include/android-base/strings.h b/include/android-base/strings.h
index 95d6077..e794540 100644
--- a/include/android-base/strings.h
+++ b/include/android-base/strings.h
@@ -104,5 +104,8 @@
 [[nodiscard]] std::string StringReplace(std::string_view s, std::string_view from,
                                         std::string_view to, bool all);
 
+// Converts an errno number to its error message string.
+std::string ErrnoNumberAsString(int errnum);
+
 }  // namespace base
 }  // namespace android
diff --git a/include/android-base/test_utils.h b/include/android-base/test_utils.h
index f3d7cb0..29dc394 100644
--- a/include/android-base/test_utils.h
+++ b/include/android-base/test_utils.h
@@ -18,6 +18,7 @@
 
 #include <regex>
 #include <string>
+#include <type_traits>
 
 #include <android-base/file.h>
 #include <android-base/macros.h>
@@ -53,34 +54,44 @@
   CapturedStdout() : CapturedStdFd(STDOUT_FILENO) {}
 };
 
-#define ASSERT_MATCH(str, pattern)                                           \
-  do {                                                                       \
-    auto __s = (str);                                                        \
-    if (!std::regex_search(__s, std::regex((pattern)))) {                    \
-      FAIL() << "regex mismatch: expected " << (pattern) << " in:\n" << __s; \
-    }                                                                        \
+#define __LIBBASE_GENERIC_REGEX_SEARCH(__s, __pattern) \
+  (std::regex_search(__s, std::basic_regex<std::decay<decltype(__s[0])>::type>((__pattern))))
+
+#define ASSERT_MATCH(__string, __pattern)                                      \
+  do {                                                                         \
+    auto __s = (__string);                                                     \
+    if (!__LIBBASE_GENERIC_REGEX_SEARCH(__s, (__pattern))) {                   \
+      FAIL() << "regex mismatch: expected " << (__pattern) << " in:\n" << __s; \
+    }                                                                          \
   } while (0)
 
-#define ASSERT_NOT_MATCH(str, pattern)                                                   \
-  do {                                                                                   \
-    auto __s = (str);                                                                    \
-    if (std::regex_search(__s, std::regex((pattern)))) {                                 \
-      FAIL() << "regex mismatch: expected to not find " << (pattern) << " in:\n" << __s; \
-    }                                                                                    \
+#define ASSERT_NOT_MATCH(__string, __pattern)                                              \
+  do {                                                                                     \
+    auto __s = (__string);                                                                 \
+    if (__LIBBASE_GENERIC_REGEX_SEARCH(__s, (__pattern))) {                                \
+      FAIL() << "regex mismatch: expected to not find " << (__pattern) << " in:\n" << __s; \
+    }                                                                                      \
   } while (0)
 
-#define EXPECT_MATCH(str, pattern)                                                  \
-  do {                                                                              \
-    auto __s = (str);                                                               \
-    if (!std::regex_search(__s, std::regex((pattern)))) {                           \
-      ADD_FAILURE() << "regex mismatch: expected " << (pattern) << " in:\n" << __s; \
-    }                                                                               \
+#define EXPECT_MATCH(__string, __pattern)                                             \
+  do {                                                                                \
+    auto __s = (__string);                                                            \
+    if (!__LIBBASE_GENERIC_REGEX_SEARCH(__s, (__pattern))) {                          \
+      ADD_FAILURE() << "regex mismatch: expected " << (__pattern) << " in:\n" << __s; \
+    }                                                                                 \
   } while (0)
 
-#define EXPECT_NOT_MATCH(str, pattern)                                                          \
-  do {                                                                                          \
-    auto __s = (str);                                                                           \
-    if (std::regex_search(__s, std::regex((pattern)))) {                                        \
-      ADD_FAILURE() << "regex mismatch: expected to not find " << (pattern) << " in:\n" << __s; \
-    }                                                                                           \
+#define EXPECT_NOT_MATCH(__string, __pattern)                                                     \
+  do {                                                                                            \
+    auto __s = (__string);                                                                        \
+    if (__LIBBASE_GENERIC_REGEX_SEARCH(__s, (__pattern))) {                                       \
+      ADD_FAILURE() << "regex mismatch: expected to not find " << (__pattern) << " in:\n" << __s; \
+    }                                                                                             \
   } while (0)
+
+extern "C" void __hwasan_init() __attribute__((weak));
+static inline bool running_with_hwasan() {
+  return &__hwasan_init != 0;
+}
+
+#define SKIP_WITH_HWASAN if (running_with_hwasan()) GTEST_SKIP()
diff --git a/include/android-base/threads.h b/include/android-base/threads.h
index dba1fc6..dbf1b47 100644
--- a/include/android-base/threads.h
+++ b/include/android-base/threads.h
@@ -24,7 +24,7 @@
 }
 }  // namespace android
 
-#if defined(__GLIBC__)
-// bionic has this Linux-specifix call, but glibc doesn't.
+#if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
+// bionic has this Linux-specifix call, but glibc and musl don't.
 extern "C" int tgkill(int tgid, int tid, int sig);
 #endif
diff --git a/include/android-base/unique_fd.h b/include/android-base/unique_fd.h
index 9ceb5db..e929e4c 100644
--- a/include/android-base/unique_fd.h
+++ b/include/android-base/unique_fd.h
@@ -20,19 +20,25 @@
 #include <errno.h>
 #include <fcntl.h>
 
-#if !defined(_WIN32)
-#include <sys/socket.h>
-#endif
-
 #include <stdio.h>
 #include <sys/types.h>
 #include <unistd.h>
 
-// DO NOT INCLUDE OTHER LIBBASE HEADERS!
+// DO NOT INCLUDE OTHER LIBBASE HEADERS HERE!
 // This file gets used in libbinder, and libbinder is used everywhere.
 // Including other headers from libbase frequently results in inclusion of
 // android-base/macros.h, which causes macro collisions.
 
+#if defined(__BIONIC__)
+#include <android/fdsan.h>
+#endif
+#if !defined(_WIN32)
+#include <sys/socket.h>
+#endif
+
+namespace android {
+namespace base {
+
 // Container for a file descriptor that automatically closes the descriptor as
 // it goes out of scope.
 //
@@ -43,47 +49,14 @@
 //
 //      return 0; // Descriptor is closed for you.
 //
+// See also the Pipe()/Socketpair()/Fdopen()/Fdopendir() functions in this file
+// that provide interoperability with the libc functions with the same (but
+// lowercase) names.
+//
 // unique_fd is also known as ScopedFd/ScopedFD/scoped_fd; mentioned here to help
 // you find this class if you're searching for one of those names.
-
-#if defined(__BIONIC__)
-#include <android/fdsan.h>
-#endif
-
-namespace android {
-namespace base {
-
-struct DefaultCloser {
-#if defined(__BIONIC__)
-  static void Tag(int fd, void* old_addr, void* new_addr) {
-    if (android_fdsan_exchange_owner_tag) {
-      uint64_t old_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD,
-                                                        reinterpret_cast<uint64_t>(old_addr));
-      uint64_t new_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD,
-                                                        reinterpret_cast<uint64_t>(new_addr));
-      android_fdsan_exchange_owner_tag(fd, old_tag, new_tag);
-    }
-  }
-  static void Close(int fd, void* addr) {
-    if (android_fdsan_close_with_tag) {
-      uint64_t tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD,
-                                                    reinterpret_cast<uint64_t>(addr));
-      android_fdsan_close_with_tag(fd, tag);
-    } else {
-      close(fd);
-    }
-  }
-#else
-  static void Close(int fd) {
-    // Even if close(2) fails with EINTR, the fd will have been closed.
-    // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone
-    // else's fd.
-    // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
-    ::close(fd);
-  }
-#endif
-};
-
+//
+// unique_fd itself is a specialization of unique_fd_impl with a default closer.
 template <typename Closer>
 class unique_fd_impl final {
  public:
@@ -175,11 +148,48 @@
   }
 };
 
+// The actual details of closing are factored out to support unusual cases.
+// Almost everyone will want this DefaultCloser, which handles fdsan on bionic.
+struct DefaultCloser {
+#if defined(__BIONIC__)
+  static void Tag(int fd, void* old_addr, void* new_addr) {
+    if (android_fdsan_exchange_owner_tag) {
+      uint64_t old_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD,
+                                                        reinterpret_cast<uint64_t>(old_addr));
+      uint64_t new_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD,
+                                                        reinterpret_cast<uint64_t>(new_addr));
+      android_fdsan_exchange_owner_tag(fd, old_tag, new_tag);
+    }
+  }
+  static void Close(int fd, void* addr) {
+    if (android_fdsan_close_with_tag) {
+      uint64_t tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD,
+                                                    reinterpret_cast<uint64_t>(addr));
+      android_fdsan_close_with_tag(fd, tag);
+    } else {
+      close(fd);
+    }
+  }
+#else
+  static void Close(int fd) {
+    // Even if close(2) fails with EINTR, the fd will have been closed.
+    // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone
+    // else's fd.
+    // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
+    ::close(fd);
+  }
+#endif
+};
+
 using unique_fd = unique_fd_impl<DefaultCloser>;
 
 #if !defined(_WIN32)
 
 // Inline functions, so that they can be used header-only.
+
+// See pipe(2).
+// This helper hides the details of converting to unique_fd, and also hides the
+// fact that macOS doesn't support O_CLOEXEC or O_NONBLOCK directly.
 template <typename Closer>
 inline bool Pipe(unique_fd_impl<Closer>* read, unique_fd_impl<Closer>* write,
                  int flags = O_CLOEXEC) {
@@ -218,6 +228,8 @@
   return true;
 }
 
+// See socketpair(2).
+// This helper hides the details of converting to unique_fd.
 template <typename Closer>
 inline bool Socketpair(int domain, int type, int protocol, unique_fd_impl<Closer>* left,
                        unique_fd_impl<Closer>* right) {
@@ -230,11 +242,14 @@
   return true;
 }
 
+// See socketpair(2).
+// This helper hides the details of converting to unique_fd.
 template <typename Closer>
 inline bool Socketpair(int type, unique_fd_impl<Closer>* left, unique_fd_impl<Closer>* right) {
   return Socketpair(AF_UNIX, type, 0, left, right);
 }
 
+// See fdopen(3).
 // Using fdopen with unique_fd correctly is more annoying than it should be,
 // because fdopen doesn't close the file descriptor received upon failure.
 inline FILE* Fdopen(unique_fd&& ufd, const char* mode) {
@@ -246,6 +261,7 @@
   return file;
 }
 
+// See fdopendir(3).
 // Using fdopendir with unique_fd correctly is more annoying than it should be,
 // because fdopen doesn't close the file descriptor received upon failure.
 inline DIR* Fdopendir(unique_fd&& ufd) {
@@ -259,7 +275,20 @@
 
 #endif  // !defined(_WIN32)
 
-// A wrapper type that can be implicitly constructed from either int or unique_fd.
+// A wrapper type that can be implicitly constructed from either int or
+// unique_fd. This supports cases where you don't actually own the file
+// descriptor, and can't take ownership, but are temporarily acting as if
+// you're the owner.
+//
+// One example would be a function that needs to also allow
+// STDERR_FILENO, not just a newly-opened fd. Another example would be JNI code
+// that's using a file descriptor that's actually owned by a
+// ParcelFileDescriptor or whatever on the Java side, but where the JNI code
+// would like to enforce this weaker sense of "temporary ownership".
+//
+// If you think of unique_fd as being like std::string in that represents
+// ownership, borrowed_fd is like std::string_view (and int is like const
+// char*).
 struct borrowed_fd {
   /* implicit */ borrowed_fd(int fd) : fd_(fd) {}  // NOLINT
   template <typename T>
diff --git a/logging.cpp b/logging.cpp
index 4942e2f..e6c02ba 100644
--- a/logging.cpp
+++ b/logging.cpp
@@ -62,11 +62,9 @@
 namespace base {
 
 // BSD-based systems like Android/macOS have getprogname(). Others need us to provide one.
-#if defined(__GLIBC__) || defined(_WIN32)
+#if !defined(__APPLE__) && !defined(__BIONIC__)
 static const char* getprogname() {
-#if defined(__GLIBC__)
-  return program_invocation_short_name;
-#elif defined(_WIN32)
+#ifdef _WIN32
   static bool first = true;
   static char progname[MAX_PATH] = {};
 
@@ -77,6 +75,8 @@
   }
 
   return progname;
+#else
+  return program_invocation_short_name;
 #endif
 }
 #endif
@@ -100,7 +100,7 @@
 #if defined(__linux__)
 static int OpenKmsg() {
 #if defined(__ANDROID__)
-  // pick up 'file w /dev/kmsg' environment from daemon's init rc file
+  // pick up 'file /dev/kmsg w' environment from daemon's init rc file
   const auto val = getenv("ANDROID_FILE__dev_kmsg");
   if (val != nullptr) {
     int fd;
diff --git a/mapped_file.cpp b/mapped_file.cpp
index fff3453..91d0b0f 100644
--- a/mapped_file.cpp
+++ b/mapped_file.cpp
@@ -63,8 +63,8 @@
     }
     return nullptr;
   }
-  void* base = MapViewOfFile(handle, (prot & PROT_WRITE) ? FILE_MAP_ALL_ACCESS : FILE_MAP_READ, 0,
-                             file_offset, file_length);
+  void* base = MapViewOfFile(handle, (prot & PROT_WRITE) ? FILE_MAP_ALL_ACCESS : FILE_MAP_READ,
+                             (file_offset >> 32), file_offset, file_length);
   if (base == nullptr) {
     CloseHandle(handle);
     return nullptr;
diff --git a/posix_strerror_r.cpp b/posix_strerror_r.cpp
new file mode 100644
index 0000000..6428a98
--- /dev/null
+++ b/posix_strerror_r.cpp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/* Undefine _GNU_SOURCE so that this compilation unit can access the
+ * posix version of strerror_r */
+#undef _GNU_SOURCE
+#include <string.h>
+
+namespace android {
+namespace base {
+
+extern "C" int posix_strerror_r(int errnum, char* buf, size_t buflen) {
+#ifdef _WIN32
+  return strerror_s(buf, buflen, errnum);
+#else
+  return strerror_r(errnum, buf, buflen);
+#endif
+}
+
+}  // namespace base
+}  // namespace android
diff --git a/result_test.cpp b/result_test.cpp
index c0ac0fd..19b48c3 100644
--- a/result_test.cpp
+++ b/result_test.cpp
@@ -15,15 +15,25 @@
  */
 
 #include "android-base/result.h"
-
+#include <utils/ErrorsMacros.h>
 #include "errno.h"
 
 #include <istream>
+#include <memory>
 #include <string>
+#include <type_traits>
 
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
+#include "android-base/result-gmock.h"
+
 using namespace std::string_literals;
+using ::testing::Eq;
+using ::testing::ExplainMatchResult;
+using ::testing::HasSubstr;
+using ::testing::Not;
+using ::testing::StartsWith;
 
 namespace android {
 namespace base {
@@ -183,6 +193,49 @@
   EXPECT_EQ(error_text + ": " + strerror(test_errno), result2.error().message());
 }
 
+enum class CustomError { A, B };
+
+struct CustomErrorWrapper {
+  CustomErrorWrapper() : val_(CustomError::A) {}
+  CustomErrorWrapper(const CustomError& e) : val_(e) {}
+  CustomError value() const { return val_; }
+  operator CustomError() const { return value(); }
+  std::string print() const {
+    switch (val_) {
+      case CustomError::A:
+        return "A";
+      case CustomError::B:
+        return "B";
+    }
+  }
+  CustomError val_;
+};
+
+#define NewCustomError(e) Error<CustomErrorWrapper>(CustomError::e)
+
+TEST(result, result_with_custom_errorcode) {
+  Result<void, CustomError> ok = {};
+  EXPECT_RESULT_OK(ok);
+  ok.value();  // should not crash
+  EXPECT_DEATH(ok.error(), "");
+
+  auto error_text = "test error"s;
+  Result<void, CustomError> err = NewCustomError(A) << error_text;
+
+  EXPECT_FALSE(err.ok());
+  EXPECT_FALSE(err.has_value());
+
+  EXPECT_EQ(CustomError::A, err.error().code());
+  EXPECT_EQ(error_text + ": A", err.error().message());
+}
+
+Result<std::string, CustomError> success_or_fail(bool success) {
+  if (success)
+    return "success";
+  else
+    return NewCustomError(A) << "fail";
+}
+
 TEST(result, constructor_forwarding) {
   auto result = Result<std::string>(std::in_place, 5, 'a');
 
@@ -192,6 +245,249 @@
   EXPECT_EQ("aaaaa", *result);
 }
 
+TEST(result, unwrap_or_return) {
+  auto f = [](bool success) -> Result<size_t, CustomError> {
+    return OR_RETURN(success_or_fail(success)).size();
+  };
+
+  auto r = f(true);
+  EXPECT_TRUE(r.ok());
+  EXPECT_EQ(strlen("success"), *r);
+
+  auto s = f(false);
+  EXPECT_FALSE(s.ok());
+  EXPECT_EQ(CustomError::A, s.error().code());
+  EXPECT_EQ("fail: A", s.error().message());
+}
+
+TEST(result, unwrap_or_return_errorcode) {
+  auto f = [](bool success) -> CustomError {
+    // Note that we use the same OR_RETURN macro for different return types: Result<U, CustomError>
+    // and CustomError.
+    std::string val = OR_RETURN(success_or_fail(success));
+    EXPECT_EQ("success", val);
+    return CustomError::B;
+  };
+
+  auto r = f(true);
+  EXPECT_EQ(CustomError::B, r);
+
+  auto s = f(false);
+  EXPECT_EQ(CustomError::A, s);
+}
+
+TEST(result, unwrap_or_fatal) {
+  auto r = OR_FATAL(success_or_fail(true));
+  EXPECT_EQ("success", r);
+
+  EXPECT_DEATH(OR_FATAL(success_or_fail(false)), "fail: A");
+}
+
+TEST(result, unwrap_ambiguous_int) {
+  const std::string firstSuccess{"a"};
+  constexpr int secondSuccess = 5;
+  auto enum_success_or_fail = [&](bool success) -> Result<std::string, StatusT> {
+    if (success) return firstSuccess;
+    return ResultError<StatusT>("Fail", 10);
+  };
+  auto f = [&](bool success) -> Result<int, StatusT> {
+    auto val = OR_RETURN(enum_success_or_fail(success));
+    EXPECT_EQ(firstSuccess, val);
+    return secondSuccess;
+  };
+
+  auto r = f(true);
+  ASSERT_TRUE(r.ok());
+  EXPECT_EQ(r.value(), secondSuccess);
+  auto s = f(false);
+  ASSERT_TRUE(!s.ok());
+  EXPECT_EQ(s.error().code(), 10);
+}
+
+TEST(result, unwrap_ambiguous_uint_conv) {
+  const std::string firstSuccess{"a"};
+  constexpr size_t secondSuccess = 5ull;
+  auto enum_success_or_fail = [&](bool success) -> Result<std::string, StatusT> {
+    if (success) return firstSuccess;
+    return ResultError<StatusT>("Fail", 10);
+  };
+
+  auto f = [&](bool success) -> Result<size_t, StatusT> {
+    auto val = OR_RETURN(enum_success_or_fail(success));
+    EXPECT_EQ(firstSuccess, val);
+    return secondSuccess;
+  };
+
+  auto r = f(true);
+  ASSERT_TRUE(r.ok());
+  EXPECT_EQ(r.value(), secondSuccess);
+  auto s = f(false);
+  ASSERT_TRUE(!s.ok());
+  EXPECT_EQ(s.error().code(), 10);
+}
+
+struct IntConst {
+    int val_;
+    template <typename T, typename = std::enable_if_t<std::is_convertible_v<T, int>>>
+    IntConst(T&& val) : val_(val) {}
+    operator status_t() {return val_;}
+};
+
+TEST(result, unwrap_ambiguous_constructible) {
+  constexpr int firstSuccess = 5;
+  constexpr int secondSuccess = 7;
+  struct A {
+    A (int val) : val_(val) {}
+    operator status_t() { return 0; }
+    int val_;
+  };
+  // If this returns Result<A, ...> instead of Result<IntConst, ...>,
+  // compilation fails unless we compile with c++20
+  auto enum_success_or_fail = [&](bool success) -> Result<IntConst, StatusT, false> {
+    if (success) return firstSuccess;
+    return ResultError<StatusT, false>(10);
+  };
+  auto f = [&](bool success) -> Result<IntConst, StatusT, false> {
+    auto val = OR_RETURN(enum_success_or_fail(success));
+    EXPECT_EQ(firstSuccess, val.val_);
+    return secondSuccess;
+  };
+  auto r = f(true);
+  EXPECT_EQ(r.value().val_, secondSuccess);
+  auto s = f(false);
+  EXPECT_EQ(s.error().code(), 10);
+}
+
+struct Dangerous {};
+struct ImplicitFromDangerous {
+  ImplicitFromDangerous(Dangerous);
+};
+template <typename U>
+struct Templated {
+    U val_;
+    template <typename T, typename=std::enable_if_t<std::is_convertible_v<T, U>>>
+    Templated(T val) : val_(val) {}
+};
+
+
+TEST(result, dangerous_result_conversion) {
+  ResultError<Dangerous, false> error {Dangerous{}};
+  Result<Templated<Dangerous>, Dangerous, false> surprise {error};
+  EXPECT_TRUE(!surprise.ok());
+  Result<Templated<ImplicitFromDangerous>, Dangerous, false> surprise2 {error};
+  EXPECT_TRUE(!surprise2.ok());
+}
+
+TEST(result, generic_convertible) {
+  const std::string firstSuccess{"a"};
+  struct A {};
+  struct B {
+    operator A() {return A{};}
+  };
+
+  auto enum_success_or_fail = [&](bool success) -> Result<std::string, B> {
+    if (success) return firstSuccess;
+    return ResultError<B>("Fail", B{});
+  };
+  auto f = [&](bool success) -> Result<A, B> {
+    auto val = OR_RETURN(enum_success_or_fail(success));
+    EXPECT_EQ(firstSuccess, val);
+    return A{};
+  };
+
+  auto r = f(true);
+  EXPECT_TRUE(r.ok());
+  auto s = f(false);
+  EXPECT_TRUE(!s.ok());
+}
+
+TEST(result, generic_exact) {
+  const std::string firstSuccess{"a"};
+  struct A {};
+  auto enum_success_or_fail = [&](bool success) -> Result<std::string, A> {
+    if (success) return firstSuccess;
+    return ResultError<A>("Fail", A{});
+  };
+  auto f = [&](bool success) -> Result<A, A> {
+    auto val = OR_RETURN(enum_success_or_fail(success));
+    EXPECT_EQ(firstSuccess, val);
+    return A{};
+  };
+
+  auto r = f(true);
+  EXPECT_TRUE(r.ok());
+  auto s = f(false);
+  EXPECT_TRUE(!s.ok());
+}
+
+struct MyData {
+  const int data;
+  static int copy_constructed;
+  static int move_constructed;
+  explicit MyData(int d) : data(d) {}
+  MyData(const MyData& other) : data(other.data) { copy_constructed++; }
+  MyData(MyData&& other) : data(other.data) { move_constructed++; }
+  MyData& operator=(const MyData&) = delete;
+  MyData& operator=(MyData&&) = delete;
+};
+
+int MyData::copy_constructed = 0;
+int MyData::move_constructed = 0;
+
+TEST(result, unwrap_does_not_incur_additional_copying) {
+  MyData::copy_constructed = 0;
+  MyData::move_constructed = 0;
+  auto f = []() -> Result<MyData> { return MyData{10}; };
+
+  [&]() -> Result<void> {
+    int data = OR_RETURN(f()).data;
+    EXPECT_EQ(10, data);
+    EXPECT_EQ(0, MyData::copy_constructed);
+    // Moved once when MyData{10} is returned as Result<MyData> in the lambda f.
+    // Moved once again when the variable d is constructed from OR_RETURN.
+    EXPECT_EQ(2, MyData::move_constructed);
+    return {};
+  }();
+}
+
+TEST(result, supports_move_only_type) {
+  auto f = [](bool success) -> Result<std::unique_ptr<std::string>> {
+    if (success) return std::make_unique<std::string>("hello");
+    return Error() << "error";
+  };
+
+  auto g = [&](bool success) -> Result<std::unique_ptr<std::string>> {
+    auto r = OR_RETURN(f(success));
+    EXPECT_EQ("hello", *(r.get()));
+    return std::make_unique<std::string>("world");
+  };
+
+  auto s = g(true);
+  EXPECT_RESULT_OK(s);
+  EXPECT_EQ("world", *(s->get()));
+
+  auto t = g(false);
+  EXPECT_FALSE(t.ok());
+  EXPECT_EQ("error", t.error().message());
+}
+
+TEST(result, unique_ptr) {
+  using testing::Ok;
+
+  auto return_unique_ptr = [](bool success) -> Result<std::unique_ptr<int>> {
+    auto result = OR_RETURN(Result<std::unique_ptr<int>>(std::make_unique<int>(3)));
+    if (!success) {
+      return Error() << __func__ << " failed.";
+    }
+    return result;
+  };
+  Result<std::unique_ptr<int>> result1 = return_unique_ptr(false);
+  ASSERT_THAT(result1, Not(Ok()));
+  Result<std::unique_ptr<int>> result2 = return_unique_ptr(true);
+  ASSERT_THAT(result2, Ok());
+  EXPECT_EQ(**result2, 3);
+}
+
 struct ConstructorTracker {
   static size_t constructor_called;
   static size_t copy_constructor_called;
@@ -418,5 +714,107 @@
             outer.error().message());
 }
 
+TEST(result, error_without_message) {
+  constexpr bool include_message = false;
+  Result<void, Errno, include_message> res = Error<Errno, include_message>(10);
+  EXPECT_FALSE(res.ok());
+  EXPECT_EQ(10, res.error().code());
+  EXPECT_EQ(sizeof(int), sizeof(res.error()));
+}
+
+namespace testing {
+
+class Listener : public ::testing::MatchResultListener {
+ public:
+  Listener() : MatchResultListener(&ss_) {}
+  ~Listener() = default;
+  std::string message() const { return ss_.str(); }
+
+ private:
+  std::stringstream ss_;
+};
+
+class ResultMatchers : public ::testing::Test {
+ public:
+  Result<int> result = 1;
+  Result<int> error = Error(EBADF) << "error message";
+  Listener listener;
+};
+
+TEST_F(ResultMatchers, ok_result) {
+  EXPECT_TRUE(ExplainMatchResult(Ok(), result, &listener));
+  EXPECT_THAT(listener.message(), Eq("result is OK"));
+}
+
+TEST_F(ResultMatchers, ok_error) {
+  EXPECT_FALSE(ExplainMatchResult(Ok(), error, &listener));
+  EXPECT_THAT(listener.message(), StartsWith("error is"));
+  EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
+  EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
+}
+
+TEST_F(ResultMatchers, not_ok_result) {
+  EXPECT_FALSE(ExplainMatchResult(Not(Ok()), result, &listener));
+  EXPECT_THAT(listener.message(), Eq("result is OK"));
+}
+
+TEST_F(ResultMatchers, not_ok_error) {
+  EXPECT_TRUE(ExplainMatchResult(Not(Ok()), error, &listener));
+  EXPECT_THAT(listener.message(), StartsWith("error is"));
+  EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
+  EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
+}
+
+TEST_F(ResultMatchers, has_value_result) {
+  EXPECT_TRUE(ExplainMatchResult(HasValue(*result), result, &listener));
+}
+
+TEST_F(ResultMatchers, has_value_wrong_result) {
+  EXPECT_FALSE(ExplainMatchResult(HasValue(*result + 1), result, &listener));
+}
+
+TEST_F(ResultMatchers, has_value_error) {
+  EXPECT_FALSE(ExplainMatchResult(HasValue(*result), error, &listener));
+  EXPECT_THAT(listener.message(), StartsWith("error is"));
+  EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
+  EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
+}
+
+TEST_F(ResultMatchers, has_error_code_result) {
+  EXPECT_FALSE(ExplainMatchResult(HasError(WithCode(error.error().code())), result, &listener));
+  EXPECT_THAT(listener.message(), Eq("result is OK"));
+}
+
+TEST_F(ResultMatchers, has_error_code_wrong_code) {
+  EXPECT_FALSE(ExplainMatchResult(HasError(WithCode(error.error().code() + 1)), error, &listener));
+  EXPECT_THAT(listener.message(), StartsWith("actual error is"));
+  EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
+}
+
+TEST_F(ResultMatchers, has_error_code_correct_code) {
+  EXPECT_TRUE(ExplainMatchResult(HasError(WithCode(error.error().code())), error, &listener));
+  EXPECT_THAT(listener.message(), StartsWith("actual error is"));
+  EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
+}
+
+TEST_F(ResultMatchers, has_error_message_result) {
+  EXPECT_FALSE(
+      ExplainMatchResult(HasError(WithMessage(error.error().message())), result, &listener));
+  EXPECT_THAT(listener.message(), Eq("result is OK"));
+}
+
+TEST_F(ResultMatchers, has_error_message_wrong_message) {
+  EXPECT_FALSE(ExplainMatchResult(HasError(WithMessage("foo")), error, &listener));
+  EXPECT_THAT(listener.message(), StartsWith("actual error is"));
+  EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
+}
+
+TEST_F(ResultMatchers, has_error_message_correct_message) {
+  EXPECT_TRUE(ExplainMatchResult(HasError(WithMessage(error.error().message())), error, &listener));
+  EXPECT_THAT(listener.message(), StartsWith("actual error is"));
+  EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
+}
+
+}  // namespace testing
 }  // namespace base
 }  // namespace android
diff --git a/result_test_constraint.cpp b/result_test_constraint.cpp
new file mode 100644
index 0000000..253a276
--- /dev/null
+++ b/result_test_constraint.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Since result has c++20 conditional behavior, we compile with std=c++20 to
+// ensure functionality in both cases. Instead of duplicating the file, we will
+// include, since this test is not linked against anything.
+// This test can be removed when we move to c++20.
+#include "result_test.cpp"
diff --git a/strings.cpp b/strings.cpp
index 8f3c7d9..deb6e28 100644
--- a/strings.cpp
+++ b/strings.cpp
@@ -16,12 +16,18 @@
 
 #include "android-base/strings.h"
 
+#include "android-base/stringprintf.h"
+
 #include <stdlib.h>
 #include <string.h>
 
 #include <string>
 #include <vector>
 
+// Wraps the posix version of strerror_r to make it available in translation units
+// that define _GNU_SOURCE.
+extern "C" int posix_strerror_r(int errnum, char* buf, size_t buflen);
+
 namespace android {
 namespace base {
 
@@ -152,5 +158,15 @@
   return result;
 }
 
+std::string ErrnoNumberAsString(int errnum) {
+  char buf[100];
+  buf[0] = '\0';
+  int strerror_err = posix_strerror_r(errnum, buf, sizeof(buf));
+  if (strerror_err < 0) {
+    return StringPrintf("Failed to convert errno %d to string: %d", errnum, strerror_err);
+  }
+  return buf;
+}
+
 }  // namespace base
 }  // namespace android
diff --git a/strings_test.cpp b/strings_test.cpp
index 7a57489..fb111b8 100644
--- a/strings_test.cpp
+++ b/strings_test.cpp
@@ -400,3 +400,7 @@
   ASSERT_EQ("xxyzx", android::base::StringReplace("abcxyzabc", "abc", "x", true));
   ASSERT_EQ("<xx>", android::base::StringReplace("<abcabc>", "abc", "x", true));
 }
+
+TEST(strings, ErrnoNumberAsString) {
+  EXPECT_EQ("No such file or directory", android::base::ErrnoNumberAsString(ENOENT));
+}
diff --git a/test_utils_test.cpp b/test_utils_test.cpp
index d08d5d6..10e8a2a 100644
--- a/test_utils_test.cpp
+++ b/test_utils_test.cpp
@@ -27,21 +27,33 @@
 TEST(TestUtilsTest, AssertMatch) {
   ASSERT_MATCH("foobar", R"(fo+baz?r)");
   EXPECT_FATAL_FAILURE(ASSERT_MATCH("foobar", R"(foobaz)"), "regex mismatch");
+
+  ASSERT_MATCH(L"foobar", LR"(fo+baz?r)");
+  EXPECT_FATAL_FAILURE(ASSERT_MATCH(L"foobar", LR"(foobaz)"), "regex mismatch");
 }
 
 TEST(TestUtilsTest, AssertNotMatch) {
   ASSERT_NOT_MATCH("foobar", R"(foobaz)");
   EXPECT_FATAL_FAILURE(ASSERT_NOT_MATCH("foobar", R"(foobar)"), "regex mismatch");
+
+  ASSERT_NOT_MATCH(L"foobar", LR"(foobaz)");
+  EXPECT_FATAL_FAILURE(ASSERT_NOT_MATCH(L"foobar", LR"(foobar)"), "regex mismatch");
 }
 
 TEST(TestUtilsTest, ExpectMatch) {
   EXPECT_MATCH("foobar", R"(fo+baz?r)");
   EXPECT_NONFATAL_FAILURE(EXPECT_MATCH("foobar", R"(foobaz)"), "regex mismatch");
+
+  EXPECT_MATCH(L"foobar", LR"(fo+baz?r)");
+  EXPECT_NONFATAL_FAILURE(EXPECT_MATCH(L"foobar", LR"(foobaz)"), "regex mismatch");
 }
 
 TEST(TestUtilsTest, ExpectNotMatch) {
   EXPECT_NOT_MATCH("foobar", R"(foobaz)");
   EXPECT_NONFATAL_FAILURE(EXPECT_NOT_MATCH("foobar", R"(foobar)"), "regex mismatch");
+
+  EXPECT_NOT_MATCH(L"foobar", LR"(foobaz)");
+  EXPECT_NONFATAL_FAILURE(EXPECT_NOT_MATCH(L"foobar", LR"(foobar)"), "regex mismatch");
 }
 
 TEST(TestUtilsTest, CaptureStdout_smoke) {
diff --git a/threads.cpp b/threads.cpp
index 48f6197..6d7d7c6 100644
--- a/threads.cpp
+++ b/threads.cpp
@@ -47,7 +47,7 @@
 }  // namespace base
 }  // namespace android
 
-#if defined(__GLIBC__)
+#if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
 int tgkill(int tgid, int tid, int sig) {
   return syscall(__NR_tgkill, tgid, tid, sig);
 }