/** * \file misc/sys-wrapper.hh * \brief SysWrapper declaration. */ #pragma once #include #include #include namespace sys { /** * \class SysWrapper * \brief Wrapping around syscalls to convert failure into exceptions. * * Wrapping syscalls this way helps to insure the RAII idiom. */ template class SysWrapper { public: SysWrapper(SysRetType syscall(Args...)) : syscall_{syscall} {} /* Needs template to enable universal referencing. Template deduction should be done automatically. */ template RetType operator()(UniversalArgs&&... args) { SysRetType ret; do { errno = 0; ret = syscall_(std::forward(args)...); } while (errno == EINTR); if (ret == SysRetType(-1) && errno != EWOULDBLOCK && errno != EAGAIN) { throw std::system_error(errno, std::system_category()); } return RetType(ret); } private: std::function syscall_; }; /** * \brief Helper function to build SysWrapper. */ template SysWrapper make_wrapper(SysRetType syscall(Args...)) { return SysWrapper(syscall); } } // namespace sys