1// Copyright (c) 2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/rand_util.h"
6#include "base/rand_util_c.h"
7
8#include <errno.h>
9#include <fcntl.h>
10#include <unistd.h>
11
12#include "base/file_util.h"
13#include "base/lazy_instance.h"
14#include "base/logging.h"
15
16namespace {
17
18// We keep the file descriptor for /dev/urandom around so we don't need to
19// reopen it (which is expensive), and since we may not even be able to reopen
20// it if we are later put in a sandbox. This class wraps the file descriptor so
21// we can use LazyInstance to handle opening it on the first access.
22class URandomFd {
23 public:
24  URandomFd() {
25    fd_ = open("/dev/urandom", O_RDONLY);
26    CHECK_GE(fd_, 0) << "Cannot open /dev/urandom: " << errno;
27  }
28
29  ~URandomFd() {
30    close(fd_);
31  }
32
33  int fd() const { return fd_; }
34
35 private:
36  int fd_;
37};
38
39base::LazyInstance<URandomFd> g_urandom_fd(base::LINKER_INITIALIZED);
40
41}  // namespace
42
43namespace base {
44
45uint64 RandUint64() {
46  uint64 number;
47
48  int urandom_fd = g_urandom_fd.Pointer()->fd();
49  bool success = file_util::ReadFromFD(urandom_fd,
50                                       reinterpret_cast<char*>(&number),
51                                       sizeof(number));
52  CHECK(success);
53
54  return number;
55}
56
57}  // namespace base
58
59int GetUrandomFD(void) {
60  return g_urandom_fd.Pointer()->fd();
61}
62