53 lines
1.3 KiB
Diff
53 lines
1.3 KiB
Diff
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.
|
|
|
|
Index: libstdc++-v3/src/c++11/random.cc
|
|
===================================================================
|
|
--- libstdc++-v3/src/c++11/random.cc (revision 228467)
|
|
+++ libstdc++-v3/src/c++11/random.cc (working copy)
|
|
@@ -30,6 +30,11 @@
|
|
# include <cpuid.h>
|
|
#endif
|
|
|
|
+#include <cerrno>
|
|
+
|
|
+#ifdef _GLIBCXX_HAVE_UNISTD_H
|
|
+# include <unistd.h>
|
|
+#endif
|
|
|
|
namespace std _GLIBCXX_VISIBILITY(default)
|
|
{
|
|
@@ -126,8 +131,27 @@ namespace std _GLIBCXX_VISIBILITY(defaul
|
|
#endif
|
|
|
|
result_type __ret;
|
|
- std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
|
|
- 1, _M_file);
|
|
+ void* p = &__ret;
|
|
+ size_t n = sizeof(result_type);
|
|
+#ifdef _GLIBCXX_HAVE_UNISTD_H
|
|
+ do
|
|
+ {
|
|
+ const int e = read(fileno(_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
|
|
+ const size_t e = std::fread(p, n, 1, _M_file);
|
|
+ if (e != 1)
|
|
+ __throw_runtime_error(__N("random_device could not be read"));
|
|
+#endif
|
|
+
|
|
return __ret;
|
|
}
|
|
|