#include #include #include #include namespace stdplus { namespace util { namespace { int sample1() { return 1; } int sample2(int val) { return val; } ssize_t sample3(int val, ssize_t* val2) { return *val2 + val; } const char* ptr(const char* p) { return p; } struct sample { int count = 3; int one() { return count++; } int two(int val) const { return val; } int* ptr() { return &count; } int* ptr2() { return nullptr; } static int s(int val) { return val; } }; int makeTrivialError(int error, const char* msg) { (void)msg; return error; } TEST(Cexec, CallCheckErrnoInt) { EXPECT_EQ(1, callCheckErrno("sample1", sample1)); EXPECT_EQ(2, callCheckErrno("sample2", &sample2, 2)); EXPECT_EQ(4, callCheckErrno("sample::s", sample::s, 4)); ssize_t v = 10; EXPECT_EQ(12, callCheckErrno("sample3", sample3, 2, &v)); constexpr auto error = "sample2 error"; try { errno = EBADF; callCheckErrno(error, sample2, -1); 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) { sample s; const sample* sp = &s; EXPECT_EQ(3, callCheckErrno("sample::one", &sample::one, s)); EXPECT_EQ(4, callCheckErrno("sample::one", &sample::one, &s)); EXPECT_EQ(5, callCheckErrno("sample::two", &sample::two, sp, 5)); constexpr auto error = "sample error"; try { errno = EBADF; callCheckErrno(error, &sample::two, sp, -1); 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, CallCheckErrnoPtr) { constexpr auto sample = "sample"; EXPECT_EQ(sample, callCheckErrno("sample1", ptr, sample)); constexpr auto error = "sample error"; try { errno = EBADF; callCheckErrno(error, &ptr, nullptr); 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, CallCheckErrnoPtrMem) { sample s; EXPECT_EQ(&s.count, callCheckErrno("sample1", &sample::ptr, &s)); constexpr auto error = "sample error"; try { errno = EBADF; callCheckErrno(error, &sample::ptr2, s); 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, CallCheckErrnoErrorFunc) { errno = EBADF; try { callCheckErrno("sample2", sample2, -1); EXPECT_TRUE(false); } catch (int error) { EXPECT_EQ(errno, error); } } TEST(Cexec, CallCheckRetInt) { EXPECT_EQ(1, callCheckRet("sample1", sample1)); EXPECT_EQ(2, callCheckRet("sample2", &sample2, 2)); EXPECT_EQ(4, callCheckRet("sample::s", sample::s, 4)); ssize_t v = 10; EXPECT_EQ(12, callCheckRet("sample3", sample3, 2, &v)); constexpr auto error = "sample2 error"; try { errno = EBADF; callCheckRet(error, sample2, -EINTR); 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) { sample s; const sample* sp = &s; EXPECT_EQ(3, callCheckRet("sample::one", &sample::one, s)); EXPECT_EQ(4, callCheckRet("sample::one", &sample::one, &s)); EXPECT_EQ(5, callCheckRet("sample::two", &sample::two, sp, 5)); constexpr auto error = "sample error"; try { errno = EBADF; callCheckRet(error, &sample::two, s, -EINTR); 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, CallCheckRetErrorFunc) { try { callCheckRet("sample2", sample2, -EBADF); EXPECT_TRUE(false); } catch (int error) { EXPECT_EQ(EBADF, error); } } } // namespace } // namespace util } // namespace stdplus