[libc++] Use ioctl when available to get random_device entropy.
Implemented the idea from D94571 to improve entropy on Linux.
Reviewed By: ldionne, #libc
Differential Revision: https://reviews.llvm.org/D94953
GitOrigin-RevId: f3b979b65e9ff81b656d26d9f2a1c731301fd445
diff --git a/src/random.cpp b/src/random.cpp
index 04adc59..7d0431e 100644
--- a/src/random.cpp
+++ b/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 <fcntl.h>
#include <unistd.h>
+#if __has_include(<sys/ioctl.h>) && __has_include(<linux/random.h>)
+#include <sys/ioctl.h>
+#include <linux/random.h>
+#endif
#elif defined(_LIBCPP_USING_NACL_RANDOM)
#include <nacl/nacl_random.h>
#endif
@@ -172,7 +177,21 @@
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<result_type>::digits)
+ return std::numeric_limits<result_type>::digits;
+
+ return ent;
+#else
+ return 0;
+#endif
}
_LIBCPP_END_NAMESPACE_STD