Home | History | Annotate | Download | only in base
      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 
     16 namespace {
     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.
     22 class 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 
     39 base::LazyInstance<URandomFd> g_urandom_fd(base::LINKER_INITIALIZED);
     40 
     41 }  // namespace
     42 
     43 namespace base {
     44 
     45 uint64 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 
     59 int GetUrandomFD(void) {
     60   return g_urandom_fd.Pointer()->fd();
     61 }
     62