diff --git a/libcxx/src/random.cpp b/libcxx/src/random.cpp index 04adc59f9bc9..7d0431e5ca54 100644 --- a/libcxx/src/random.cpp +++ b/libcxx/src/random.cpp @@ -13,6 +13,7 @@ #define _CRT_RAND_S #endif // defined(_LIBCPP_USING_WIN32_RANDOM) +#include "limits" #include "random" #include "system_error" @@ -29,6 +30,10 @@ #elif defined(_LIBCPP_USING_DEV_RANDOM) #include #include +#if __has_include() && __has_include() +#include +#include +#endif #elif defined(_LIBCPP_USING_NACL_RANDOM) #include #endif @@ -172,7 +177,21 @@ random_device::operator()() double random_device::entropy() const _NOEXCEPT { +#if defined(_LIBCPP_USING_DEV_RANDOM) && defined(RNDGETENTCNT) + int ent; + if (::ioctl(__f_, RNDGETENTCNT, &ent) < 0) return 0; + + if (ent < 0) + return 0; + + if (ent > std::numeric_limits::digits) + return std::numeric_limits::digits; + + return ent; +#else + return 0; +#endif } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/numerics/rand/rand.device/entropy.pass.cpp b/libcxx/test/std/numerics/rand/rand.device/entropy.pass.cpp index 4f09d05012ea..3f9ea85bfc05 100644 --- a/libcxx/test/std/numerics/rand/rand.device/entropy.pass.cpp +++ b/libcxx/test/std/numerics/rand/rand.device/entropy.pass.cpp @@ -16,14 +16,15 @@ #include #include +#include #include "test_macros.h" -int main(int, char**) -{ - std::random_device r; - double e = r.entropy(); - ((void)e); // Prevent unused warning +int main(int, char**) { + std::random_device r; + double e = r.entropy(); + assert(e >= 0); + assert(e <= sizeof(typename std::random_device::result_type) * CHAR_BIT); return 0; }