aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2015-09-17 16:06:42 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2015-09-17 16:06:42 +0100
commita2b4d73daf5854c40b71e0b655a9507bf6977279 (patch)
tree0dd3c7308998c3b62b6757ec7e3b42426e1828b6 /libstdc++-v3
parent2eb57e545ba21b1776371acf6cb11bc28233bd82 (diff)
downloadgcc-a2b4d73daf5854c40b71e0b655a9507bf6977279.zip
gcc-a2b4d73daf5854c40b71e0b655a9507bf6977279.tar.gz
gcc-a2b4d73daf5854c40b71e0b655a9507bf6977279.tar.bz2
Make std::random_device retry after short reads
PR libstdc++/65142 * src/c++11/random.cc (random_device::_M_getval()): Retry after short reads. From-SVN: r227872
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog4
-rw-r--r--libstdc++-v3/src/c++11/random.cc24
2 files changed, 21 insertions, 7 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c70ad43..25aa16b 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,9 @@
2015-09-17 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/65142
+ * src/c++11/random.cc (random_device::_M_getval()): Retry after short
+ reads.
+
* include/std/system_error (error_code::operator bool(),
error_condition::operator bool()): Remove redundant conditional
expression.
diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index 1d102c7..f1d6125 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -130,16 +130,26 @@ namespace std _GLIBCXX_VISIBILITY(default)
#endif
result_type __ret;
-
+ void* p = &__ret;
+ size_t n = sizeof(result_type);
#ifdef _GLIBCXX_HAVE_UNISTD_H
- auto e = 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
- auto e = 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
- if (e != sizeof(result_type))
- __throw_runtime_error(__N("random_device could not read enough bytes"));
return __ret;
}