aboutsummaryrefslogtreecommitdiff
path: root/lib/Support/Unix/Process.inc
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2012-05-08 20:38:00 +0000
committerDaniel Dunbar <daniel@zuster.org>2012-05-08 20:38:00 +0000
commit2b8f3ba8434fe7a847823c4f11d3a0cdb9c2e2ca (patch)
tree436c5cdf7ac896f28a05d4144ee80ce4919800f6 /lib/Support/Unix/Process.inc
parentab3a7fb2441403bd6723f47a5cd4c4cdb3b7d3a1 (diff)
[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
Diffstat (limited to 'lib/Support/Unix/Process.inc')
-rw-r--r--lib/Support/Unix/Process.inc20
1 files changed, 15 insertions, 5 deletions
diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
index dd855b0d3f..4e1bd5db14 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 <sys/time.h>
#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