From ba0e32abaecedf3939905bd316336f313b3dd745 Mon Sep 17 00:00:00 2001 From: Nils Maier Date: Fri, 6 Feb 2015 17:33:22 +0100 Subject: 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 --- src/SimpleRandomizer.cc | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/SimpleRandomizer.cc') 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(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(buf); size_t q = len / sizeof(result_type); auto gen = std::uniform_int_distribution(); -- cgit