From a77890c6ee0a8aacef9967a68fce85c7deaae2d8 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Fri, 7 Jan 2022 11:24:35 +0000 Subject: [PATCH] PAL netbsd (temporary until some time 2022) build fix. (#450) std::random_device seems unimplemented on this platform thus falling back to the usual /dev/urandom device for the time being. --- src/pal/pal_linux.h | 35 +---------------------------------- src/pal/pal_netbsd.h | 14 +++++++++++++- src/pal/pal_posix.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/pal/pal_linux.h b/src/pal/pal_linux.h index 438a746..39d402d 100644 --- a/src/pal/pal_linux.h +++ b/src/pal/pal_linux.h @@ -4,7 +4,6 @@ # include "../ds/bits.h" # include "pal_posix.h" -# include # include # include # include @@ -166,39 +165,7 @@ namespace snmalloc // reentrancy problem during initialisation routine. // 2. some implementations also require libstdc++ to be linked since // its APIs are not exception-free. - int flags = O_RDONLY; -# if defined(O_CLOEXEC) - flags |= O_CLOEXEC; -# endif - auto fd = open("/dev/urandom", flags, 0); - if (fd > 0) - { - auto current = std::begin(buffer); - auto target = std::end(buffer); - while (auto length = static_cast(target - current)) - { - ret = read(fd, current, length); - if (ret <= 0) - { - if (errno != EAGAIN && errno != EINTR) - { - break; - } - } - else - { - current += ret; - } - } - ret = close(fd); - SNMALLOC_ASSERT(0 == ret); - if (SNMALLOC_LIKELY(target == current)) - { - return result; - } - } - - error("Failed to get system randomness"); + return dev_urandom(); } }; } // namespace snmalloc diff --git a/src/pal/pal_netbsd.h b/src/pal/pal_netbsd.h index e91c4b2..377c1cc 100644 --- a/src/pal/pal_netbsd.h +++ b/src/pal/pal_netbsd.h @@ -3,6 +3,8 @@ #ifdef __NetBSD__ # include "pal_bsd_aligned.h" +# include + namespace snmalloc { /** @@ -26,7 +28,17 @@ namespace snmalloc * As NetBSD does not have the getentropy call, get_entropy64 will * currently fallback to C++ libraries std::random_device. */ - static constexpr uint64_t pal_features = PALBSD_Aligned::pal_features; + static constexpr uint64_t pal_features = + PALBSD_Aligned::pal_features | Entropy; + + /** + * Temporary solution while waiting getrandom support for the next release + * random_device seems unimplemented in clang for this platform + */ + static uint64_t get_entropy64() + { + return PALPOSIX::dev_urandom(); + } }; } // namespace snmalloc #endif diff --git a/src/pal/pal_posix.h b/src/pal/pal_posix.h index 6f12b04..bc05f9f 100644 --- a/src/pal/pal_posix.h +++ b/src/pal/pal_posix.h @@ -9,6 +9,7 @@ # include SNMALLOC_BACKTRACE_HEADER #endif #include +#include #include #include #include @@ -363,5 +364,48 @@ namespace snmalloc return (static_cast(ts.tv_sec) * 1000) + (static_cast(ts.tv_nsec) / 1000000); } + + static uint64_t dev_urandom() + { + union + { + uint64_t result; + char buffer[sizeof(uint64_t)]; + }; + ssize_t ret; + int flags = O_RDONLY; +#if defined(O_CLOEXEC) + flags |= O_CLOEXEC; +#endif + auto fd = open("/dev/urandom", flags, 0); + if (fd > 0) + { + auto current = std::begin(buffer); + auto target = std::end(buffer); + while (auto length = static_cast(target - current)) + { + ret = read(fd, current, length); + if (ret <= 0) + { + if (errno != EAGAIN && errno != EINTR) + { + break; + } + } + else + { + current += ret; + } + } + ret = close(fd); + SNMALLOC_ASSERT(0 == ret); + if (SNMALLOC_LIKELY(target == current)) + { + return result; + } + } + + error("Failed to get system randomness"); + } }; } // namespace snmalloc