From dbda86271e551c642a980929866fcd07082ee483 Mon Sep 17 00:00:00 2001 From: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri, 2 Oct 2015 20:51:34 +0000 Subject: [PATCH] Backport PR libstdc++/65142 fix from mainline PR libstdc++/65142 * src/c++11/random.cc (random_device::_M_getval()): Check read result and retry after short reads. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@228424 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 6 ++++++ libstdc++-v3/src/c++11/random.cc | 23 +++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) #diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog #index 6d2d628..70774cc 100644 #--- a/libstdc++-v3/ChangeLog #+++ b/libstdc++-v3/ChangeLog #@@ -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 diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc index f61daea..d175e79 100644 --- a/libstdc++-v3/src/c++11/random.cc +++ b/libstdc++-v3/src/c++11/random.cc @@ -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; } -- 1.9.4