blob: 6abf5f82f1abe3064ab10b94fdcc79d31687deae [file] [log] [blame]
[email protected]6de0fd1d2011-11-15 13:31:491// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]05f9b682008-09-29 22:18:012// 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"
[email protected]1d87fad2010-03-04 20:18:556#include "base/rand_util_c.h"
[email protected]05f9b682008-09-29 22:18:017
[email protected]09e5f47a2009-06-26 10:00:028#include <errno.h>
[email protected]05f9b682008-09-29 22:18:019#include <fcntl.h>
[email protected]05f9b682008-09-29 22:18:0110#include <unistd.h>
11
[email protected]45301492009-04-23 12:38:0812#include "base/file_util.h"
[email protected]09e5f47a2009-06-26 10:00:0213#include "base/lazy_instance.h"
[email protected]05f9b682008-09-29 22:18:0114#include "base/logging.h"
15
[email protected]09e5f47a2009-06-26 10:00:0216namespace {
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);
[email protected]a42d4632011-10-26 21:48:0026 DCHECK_GE(fd_, 0) << "Cannot open /dev/urandom: " << errno;
[email protected]09e5f47a2009-06-26 10:00:0227 }
28
29 ~URandomFd() {
30 close(fd_);
31 }
32
33 int fd() const { return fd_; }
34
35 private:
36 int fd_;
37};
38
[email protected]6de0fd1d2011-11-15 13:31:4939base::LazyInstance<URandomFd> g_urandom_fd = LAZY_INSTANCE_INITIALIZER;
[email protected]09e5f47a2009-06-26 10:00:0240
41} // namespace
42
[email protected]05f9b682008-09-29 22:18:0143namespace base {
44
[email protected]ba990122008-11-14 23:28:2945uint64 RandUint64() {
[email protected]05f9b682008-09-29 22:18:0146 uint64 number;
47
[email protected]09e5f47a2009-06-26 10:00:0248 int urandom_fd = g_urandom_fd.Pointer()->fd();
[email protected]45301492009-04-23 12:38:0849 bool success = file_util::ReadFromFD(urandom_fd,
50 reinterpret_cast<char*>(&number),
51 sizeof(number));
52 CHECK(success);
[email protected]05f9b682008-09-29 22:18:0153
54 return number;
55}
56
57} // namespace base
[email protected]1d87fad2010-03-04 20:18:5558
59int GetUrandomFD(void) {
60 return g_urandom_fd.Pointer()->fd();
61}