From: Daniel Dunbar Date: Tue, 8 May 2012 20:38:00 +0000 (+0000) Subject: [Support] Fix sys::GetRandomNumber() to always use a high quality seed. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2b8f3ba8434fe7a847823c4f11d3a0cdb9c2e2ca;p=oota-llvm.git [Support] Fix sys::GetRandomNumber() to always use a high quality seed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156414 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc index dd855b0d3ff..4e1bd5db142 100644 --- a/lib/Support/Unix/Process.inc +++ b/lib/Support/Unix/Process.inc @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "Unix.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/Support/TimeValue.h" #ifdef HAVE_SYS_TIME_H #include #endif @@ -300,13 +302,21 @@ const char *Process::ResetColor() { #if !defined(HAVE_ARC4RANDOM) static unsigned GetRandomNumberSeed() { - unsigned seed = ::time(NULL); // FIXME: It might not provide unique seed. - FILE *RandomSource = ::fopen("/dev/urandom", "r"); - if (RandomSource) { - ::fread((void *)&seed, sizeof(seed), 1, RandomSource); + // Attempt to get the initial seed from /dev/urandom, if possible. + if (FILE *RandomSource = ::fopen("/dev/urandom", "r")) { + unsigned seed; + int count = ::fread((void *)&seed, sizeof(seed), 1, RandomSource); ::fclose(RandomSource); + + // Return the seed if the read was successful. + if (count == 1) + return seed; } - return seed; + + // Otherwise, swizzle the current time and the process ID to form a reasonable + // seed. + TimeValue Now = llvm::TimeValue::now(); + return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid()); } #endif