diff mbox

Implement non-trivial std::random_device::entropy (PR libstdc++/67578)

Message ID 1495106850.1663.8.camel@stu.xidian.edu.cn
State New
Headers show

Commit Message

Xi Ruoyao May 18, 2017, 11:27 a.m. UTC
This patch use ioctl to get entropy of std::random_device using
/dev/random and /dev/urandom.

Regenerated files are mentioned in ChangeLog but not included
in the patch.

2017-03-12  Xi Ruoyao  <ryxi@stu.xidian.edu.cn>

	PR libstdc++/67578
	* config.h.in: Regenerate.
	* configure: Regenerate.
	* configure.ac: Check for linux/random.h.
	* config/abi/pre/gnu.ver: Add a new symbol.
	* include/bits/random.h (random_device::_M_getentropy):
	  Declare new function to get entropy using ioctl.
	  (random_device::entropy): Call it.
	* src/c++11/random.cc (random_device::_M_getentropy):
	  Implement new function.
	* config/abi/post/x86_64-linux-gnu/baseline_symbols.txt:
	  Regenerate.
	* config/abi/post/i386-linux-gnu/baseline_symbols.txt:
	  Regenerate.
	* config/abi/post/i486-linux-gnu/baseline_symbols.txt:
	  Regenerate.
---
 libstdc++-v3/config/abi/pre/gnu.ver                |  3 ++
 libstdc++-v3/configure.ac                          |  2 +-
 libstdc++-v3/include/bits/random.h                 |  9 +++++-
 libstdc++-v3/src/c++11/random.cc                   | 36 ++++++++++++++++++++++
 9 files changed, 55 insertions(+), 3 deletions(-)

-- 
2.7.1
diff mbox

Patch

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 3e6e70b..39ad330 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1963,6 +1963,9 @@  GLIBCXX_3.4.23 {
     _ZNSt13__future_base13_State_baseV211_Make_ready6_M_setEv;
 #endif
 
+    # std::random_device::_M_getentropy() const
+    _ZNKSt13random_device13_M_getentropyEv;
+
 } GLIBCXX_3.4.22;
 
 # Symbols in the support library (libsupc++) have their own tag.
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 8e97350..270dcba 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -237,7 +237,7 @@  AC_CHECK_HEADERS([endian.h execinfo.h float.h fp.h ieeefp.h inttypes.h \
 locale.h machine/endian.h machine/param.h nan.h stdint.h stdlib.h string.h \
 strings.h sys/ipc.h sys/isa_defs.h sys/machine.h sys/param.h \
 sys/resource.h sys/sem.h sys/stat.h sys/time.h sys/types.h unistd.h \
-wchar.h wctype.h])
+wchar.h wctype.h linux/random.h])
 
 # Only do link tests if native. Else, hardcode.
 if $GLIBCXX_IS_NATIVE; then
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index d39cc3e..bb761ec 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -1603,7 +1603,13 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     double
     entropy() const noexcept
-    { return 0.0; }
+    {
+#ifdef _GLIBCXX_USE_RANDOM_TR1
+      return this->_M_getentropy();
+#else
+      return 0.0;
+#endif
+    }
 
     result_type
     operator()()
@@ -1627,6 +1633,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     result_type _M_getval();
     result_type _M_getval_pretr1();
+    double _M_getentropy() const noexcept;
 
     union
     {
diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index df79874..414ddc3 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -38,6 +38,14 @@ 
 # include <unistd.h>
 #endif
 
+#ifdef _GLIBCXX_HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+#ifdef _GLIBCXX_HAVE_LINUX_RANDOM_H
+# include <linux/random.h>
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
   namespace
@@ -161,6 +169,34 @@  namespace std _GLIBCXX_VISIBILITY(default)
     return _M_mt();
   }
 
+  double
+  random_device::_M_getentropy() const noexcept
+  {
+#if defined _GLIBCXX_HAVE_SYS_IOCTL_H && \
+    defined _GLIBCXX_HAVE_LINUX_RANDOM_H
+    if (!_M_file)
+      return 0.0;
+
+    int fd = fileno(static_cast<FILE *>(_M_file));
+    if (fd < 0)
+      return 0.0;
+
+    int ent;
+    if (ioctl(fd, RNDGETENTCNT, &ent) < 0)
+      return 0.0;
+
+    if (ent < 0)
+      return 0.0;
+
+    if (static_cast<unsigned>(ent) > sizeof(result_type) * 8)
+      return static_cast<double>(sizeof(result_type) * 8);
+
+    return static_cast<double>(ent);
+#else
+    return 0.0;
+#endif
+  }
+
   template class mersenne_twister_engine<
     uint_fast32_t,
     32, 624, 397, 31,