util/cexec: Add lazy evaluated error checking functions

This inhibits things like error string construction until an error
actually occurs to speed up the good path.

Change-Id: I9a9350259466a2284536d50074c2c42b008da33b
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/util/cexec.cpp b/test/util/cexec.cpp
index c41c2d4..f5b7a5e 100644
--- a/test/util/cexec.cpp
+++ b/test/util/cexec.cpp
@@ -68,6 +68,9 @@
 
 TEST(Cexec, CallCheckErrnoInt)
 {
+    EXPECT_EQ(1, CHECK_ERRNO(sample1(), [](int) { throw 0; }));
+    EXPECT_EQ(1, CHECK_ERRNO(sample1(), "sample1"));
+    EXPECT_EQ(1, CHECK_ERRNO(sample1(), std::string("sample1")));
     EXPECT_EQ(1, callCheckErrno("sample1", sample1));
     EXPECT_EQ(2, callCheckErrno(std::string("sample2"), &sample2, 2));
     EXPECT_EQ(4, callCheckErrno("sample::s", sample::s, 4));
@@ -87,6 +90,19 @@
                   std::string_view(e.what(), strlen(error)));
         EXPECT_EQ(EBADF, e.code().value());
     }
+
+    try
+    {
+        errno = EBADF;
+        CHECK_ERRNO(sample2(-1), error);
+        EXPECT_TRUE(false);
+    }
+    catch (const std::system_error& e)
+    {
+        EXPECT_EQ(std::string_view(error),
+                  std::string_view(e.what(), strlen(error)));
+        EXPECT_EQ(EBADF, e.code().value());
+    }
 }
 
 TEST(Cexec, CallCheckErrnoIntMem)
@@ -164,11 +180,23 @@
     {
         EXPECT_EQ(errno, error);
     }
+
+    try
+    {
+        errno = EBADF;
+        CHECK_ERRNO(sample2(-1), [](int r) { throw r; });
+        EXPECT_TRUE(false);
+    }
+    catch (int i)
+    {
+        EXPECT_EQ(EBADF, i);
+    }
 }
 
 TEST(Cexec, CallCheckRetInt)
 {
     EXPECT_EQ(1, callCheckRet("sample1", sample1));
+    EXPECT_EQ(1, CHECK_RET(sample1(), "sample1"));
     EXPECT_EQ(2, callCheckRet(std::string("sample2"), &sample2, 2));
     EXPECT_EQ(4, callCheckRet("sample::s", sample::s, 4));
     ssize_t v = 10;
@@ -187,6 +215,19 @@
                   std::string_view(e.what(), strlen(error)));
         EXPECT_EQ(EINTR, e.code().value());
     }
+
+    try
+    {
+        errno = EBADF;
+        CHECK_RET(sample2(-EINTR), error);
+        EXPECT_TRUE(false);
+    }
+    catch (const std::system_error& e)
+    {
+        EXPECT_EQ(std::string_view(error),
+                  std::string_view(e.what(), strlen(error)));
+        EXPECT_EQ(EINTR, e.code().value());
+    }
 }
 
 TEST(Cexec, CallCheckRetIntMem)