diff options
-rw-r--r-- | fn_hook.cc | 16 |
1 files changed, 11 insertions, 5 deletions
@@ -28,10 +28,7 @@ struct hook; template <typename Derived, typename Ret, typename... Args, bool IsNoexcept> struct hook<Derived, Ret (*)(Args...) noexcept(IsNoexcept)> { // Function pointer type. - using fn_t = Ret (*)(Args...); - - // Remember whether this hook was noexcept, to be used for the outer wrapper. - static constexpr bool is_noexcept = IsNoexcept; + using fn_t = Ret (*)(Args...) noexcept(IsNoexcept); constexpr hook() noexcept = default; @@ -52,6 +49,11 @@ struct hook<Derived, Ret (*)(Args...) noexcept(IsNoexcept)> { ptr = reinterpret_cast<fn_t>(::dlsym(RTLD_NEXT, Derived::sym)); } + // Remember whether this hook was noexcept, to be used for the outer wrapper. + static constexpr bool is_noexcept() { + return IsNoexcept; + } + private: fn_t ptr = nullptr; }; @@ -74,7 +76,7 @@ private: } fn; \ } \ \ - extern "C" ret fn(__VA_ARGS__) noexcept(detail::hook_##fn::is_noexcept) + extern "C" ret fn(__VA_ARGS__) noexcept(detail::hook_##fn::is_noexcept()) // -- EXAMPLE ------------------------------------------------------------------ @@ -85,11 +87,15 @@ WRAP(ssize_t, write, int fd, const void* buf, size_t sz) { puts("wrapper write(..)"); return detail::write(fd, buf, sz); } +// glibc: write is not marked noexcept, as it is a cancellation point. +static_assert(!detail::hook_write::is_noexcept()); WRAP(pid_t, getpid) { puts("wrapper getpid()"); return detail::getpid(); } +// glibc: getpid is marked noexcept. +static_assert(detail::hook_getpid::is_noexcept()); int main() { const char msg[] = "hello moose\n"; |