diff --git a/include/ircd/util.h b/include/ircd/util.h index 87ed10aed..9511d09a2 100644 --- a/include/ircd/util.h +++ b/include/ircd/util.h @@ -820,19 +820,48 @@ struct values }; +// +// Error-checking closure for POSIX system calls. Note the usage is +// syscall(read, foo, bar, baz) not a macro like syscall(read(foo, bar, baz)); +// +template +auto +syscall(function&& f, + args&&... a) +-> typename std::enable_if::value, int>::type +{ + const int ret + { + f(std::forward(a)...) + }; + + if(unlikely(ret == ERROR_CODE)) + throw std::system_error(errno, std::system_category()); + + return ret; +} // // Error-checking closure for POSIX system calls. Note the usage is // syscall(read, foo, bar, baz) not a macro like syscall(read(foo, bar, baz)); // -template auto -syscall(function&& f, - args&&... a) +uninterruptible_syscall(function&& f, + args&&... a) +-> typename std::enable_if::value, int>::type { - const auto ret(f(a...)); - if(unlikely(long(ret) == -1)) + int ret; do + { + ret = f(std::forward(a)...); + } + while(unlikely(ret == ERROR_CODE && errno == EINTR)); + + if(unlikely(ret == ERROR_CODE)) throw std::system_error(errno, std::system_category()); return ret;