]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport PR libstdc++/65142 fix from mainline
authorJonathan Wakely <jwakely@redhat.com>
Fri, 2 Oct 2015 20:51:34 +0000 (21:51 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 2 Oct 2015 20:51:34 +0000 (21:51 +0100)
PR libstdc++/65142
* src/c++11/random.cc (random_device::_M_getval()): Check read result
and retry after short reads.

From-SVN: r228424

libstdc++-v3/ChangeLog
libstdc++-v3/src/c++11/random.cc

index 6d2d62849420e3f81f17ed94f0d55b332829d2da..70774cce9aba502cddaaa748554a228d2170c76d 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-02  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/65142
+       * src/c++11/random.cc (random_device::_M_getval()): Check read result
+       and retry after short reads.
+
 2015-09-03  Jonathan Wakely  <jwakely@redhat.com>
 
        Backport from mainline
index f61daeacb502e3af3804555c131ac2f7d6b26b92..d175e79b56d5b17a603fd0524101768b5bdd4216 100644 (file)
@@ -30,6 +30,7 @@
 # include <cpuid.h>
 #endif
 
+#include <cerrno>
 #include <cstdio>
 
 #ifdef _GLIBCXX_HAVE_UNISTD_H
@@ -129,13 +130,27 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
 
     result_type __ret;
+    void* p = &__ret;
+    size_t n = sizeof(result_type);
 #ifdef _GLIBCXX_HAVE_UNISTD_H
-    read(fileno(static_cast<FILE*>(_M_file)),
-        static_cast<void*>(&__ret), sizeof(result_type));
+    do
+      {
+       const int e = read(fileno(static_cast<FILE*>(_M_file)), p, n);
+       if (e > 0)
+         {
+           n -= e;
+           p = static_cast<char*>(p) + e;
+         }
+       else if (e != -1 || errno != EINTR)
+         __throw_runtime_error(__N("random_device could not be read"));
+      }
+    while (n > 0);
 #else
-    std::fread(static_cast<void*>(&__ret), sizeof(result_type),
-              1, static_cast<FILE*>(_M_file));
+    const size_t e = std::fread(p, n, 1, static_cast<FILE*>(_M_file));
+    if (e != 1)
+      __throw_runtime_error(__N("random_device could not be read"));
 #endif
+
     return __ret;
   }