Factor out error reporting in WriteProtected.

Partly to buff our coverage numbers, but also for improved consistency
in error reporting.

Test: treehugger
Change-Id: Iffc32833a35f9e9535c1bc3e0f7cb3c4bbba5f7f
diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h
index 8f5b32d..746f72a 100644
--- a/libc/private/WriteProtected.h
+++ b/libc/private/WriteProtected.h
@@ -40,23 +40,11 @@
 // explicitly.
 template <typename T>
 class WriteProtected {
+ public:
   static_assert(sizeof(T) < PAGE_SIZE,
                 "WriteProtected only supports contents up to PAGE_SIZE");
   static_assert(__is_pod(T), "WriteProtected only supports POD contents");
 
-  WriteProtectedContents<T> contents;
-
-  int set_protection(int prot) {
-    auto addr = &contents;
-#if __has_feature(hwaddress_sanitizer)
-    // The mprotect system call does not currently untag pointers, so do it
-    // ourselves.
-    addr = untag_address(addr);
-#endif
-    return mprotect(reinterpret_cast<void*>(addr), PAGE_SIZE, prot);
-  }
-
- public:
   WriteProtected() = default;
   BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtected);
 
@@ -64,10 +52,7 @@
     // Not strictly necessary, but this will hopefully segfault if we initialize
     // multiple times by accident.
     memset(&contents, 0, sizeof(contents));
-
-    if (set_protection(PROT_READ)) {
-      async_safe_fatal("failed to make WriteProtected nonwritable in initialize");
-    }
+    set_protection(PROT_READ);
   }
 
   const T* operator->() {
@@ -80,14 +65,23 @@
 
   template <typename Mutator>
   void mutate(Mutator mutator) {
-    if (set_protection(PROT_READ | PROT_WRITE) != 0) {
-      async_safe_fatal("failed to make WriteProtected writable in mutate: %s",
-                       strerror(errno));
-    }
+    set_protection(PROT_READ | PROT_WRITE);
     mutator(&contents.value);
-    if (set_protection(PROT_READ) != 0) {
-      async_safe_fatal("failed to make WriteProtected nonwritable in mutate: %s",
-                       strerror(errno));
+    set_protection(PROT_READ);
+  }
+
+ private:
+  WriteProtectedContents<T> contents;
+
+  void set_protection(int prot) {
+    auto addr = &contents;
+#if __has_feature(hwaddress_sanitizer)
+    // The mprotect system call does not currently untag pointers, so do it
+    // ourselves.
+    addr = untag_address(addr);
+#endif
+    if (mprotect(reinterpret_cast<void*>(addr), PAGE_SIZE, prot) == -1) {
+      async_safe_fatal("WriteProtected mprotect %x failed: %s", prot, strerror(errno));
     }
   }
 };