summaryrefslogtreecommitdiff
path: root/src/SimpleRandomizer.cc
diff options
context:
space:
mode:
authorNils Maier <maierman@web.de>2015-02-06 17:33:22 +0100
committerNils Maier <maierman@web.de>2015-02-07 17:18:45 +0100
commitba0e32abaecedf3939905bd316336f313b3dd745 (patch)
tree16df1163a667b23a7c2f5211b6d7a3324db2d614 /src/SimpleRandomizer.cc
parent9cbbe9f1bbb6d05b46fbf54b5c26cec62888ea79 (diff)
Handle linux getrandom returning EINTR on interrupts/signals
Also handle ENOTSUP failures where aria2 was build with linux headers newer than the actual running kernel. Fixes GH-336
Diffstat (limited to 'src/SimpleRandomizer.cc')
-rw-r--r--src/SimpleRandomizer.cc22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/SimpleRandomizer.cc b/src/SimpleRandomizer.cc
index 746491f1..31784c3e 100644
--- a/src/SimpleRandomizer.cc
+++ b/src/SimpleRandomizer.cc
@@ -42,6 +42,8 @@
#include "a2time.h"
#include "a2functional.h"
+#include "LogFactory.h"
+#include "fmt.h"
#ifdef HAVE_GETRANDOM_INTERFACE
# include "getrandom_linux.h"
@@ -88,10 +90,24 @@ void SimpleRandomizer::getRandomBytes(unsigned char* buf, size_t len)
#ifdef __MINGW32__
BOOL r = CryptGenRandom(provider_, len, reinterpret_cast<BYTE*>(buf));
assert(r);
-#elif defined(HAVE_GETRANDOM_INTERFACE)
- auto rv = getrandom_linux(buf, len);
- assert(rv >= 0 && (size_t)rv == len);
#else // ! __MINGW32__
+#if defined(HAVE_GETRANDOM_INTERFACE)
+ static bool have_random_support = true;
+ if (have_random_support) {
+ auto rv = getrandom_linux(buf, len);
+ if (rv != -1 || errno != ENOSYS) {
+ if (rv < -1) {
+ A2_LOG_ERROR(fmt("Failed to produce randomness: %d", errno));
+ }
+ assert(rv >= 0 && (size_t)rv == len);
+ return;
+ }
+ have_random_support = false;
+ A2_LOG_INFO("Disabled getrandom support, because kernel does not "\
+ "implement this feature (ENOSYS)");
+ }
+ // Fall through to generic implementation
+#endif // defined(HAVE_GETRANDOM_INTERFACE)
auto ubuf = reinterpret_cast<result_type*>(buf);
size_t q = len / sizeof(result_type);
auto gen = std::uniform_int_distribution<result_type>();