rand_util_posix.cc revision c7f5f8508d98d5952d42ed7648c2a8f30a4da156
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
7#include <errno.h>
8#include <fcntl.h>
9#include <unistd.h>
10
11#include "base/file_util.h"
12#include "base/lazy_instance.h"
13#include "base/logging.h"
14
15namespace {
16
17// We keep the file descriptor for /dev/urandom around so we don't need to
18// reopen it (which is expensive), and since we may not even be able to reopen
19// it if we are later put in a sandbox. This class wraps the file descriptor so
20// we can use LazyInstance to handle opening it on the first access.
21class URandomFd {
22 public:
23  URandomFd() {
24    fd_ = open("/dev/urandom", O_RDONLY);
25    CHECK(fd_ >= 0) << "Cannot open /dev/urandom: " << errno;
26  }
27
28  ~URandomFd() {
29    close(fd_);
30  }
31
32  int fd() const { return fd_; }
33
34 private:
35  int fd_;
36};
37
38base::LazyInstance<URandomFd> g_urandom_fd(base::LINKER_INITIALIZED);
39
40}  // namespace
41
42namespace base {
43
44uint64 RandUint64() {
45  uint64 number;
46
47  int urandom_fd = g_urandom_fd.Pointer()->fd();
48  bool success = file_util::ReadFromFD(urandom_fd,
49                                       reinterpret_cast<char*>(&number),
50                                       sizeof(number));
51  CHECK(success);
52
53  return number;
54}
55
56}  // namespace base
57