Home | History | Annotate | Download | only in rand.device
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // See bugs.llvm.org/PR20183
     11 //
     12 // XFAIL: with_system_cxx_lib=macosx10.11
     13 // XFAIL: with_system_cxx_lib=macosx10.10
     14 // XFAIL: with_system_cxx_lib=macosx10.9
     15 // XFAIL: with_system_cxx_lib=macosx10.8
     16 // XFAIL: with_system_cxx_lib=macosx10.7
     17 
     18 // <random>
     19 
     20 // class random_device;
     21 
     22 // explicit random_device(const string& token = implementation-defined);
     23 
     24 // For the following ctors, the standard states: "The semantics and default
     25 // value of the token parameter are implementation-defined". Implementations
     26 // therefore aren't required to accept any string, but the default shouldn't
     27 // throw.
     28 
     29 #include <random>
     30 #include <system_error>
     31 #include <cassert>
     32 
     33 #if !defined(_WIN32)
     34 #include <unistd.h>
     35 #endif
     36 
     37 #include "test_macros.h"
     38 
     39 
     40 bool is_valid_random_device(const std::string &token) {
     41 #if defined(_LIBCPP_USING_DEV_RANDOM)
     42   // Not an exhaustive list: they're the only tokens that are tested below.
     43   return token == "/dev/urandom" || token == "/dev/random";
     44 #else
     45   return token == "/dev/urandom";
     46 #endif
     47 }
     48 
     49 void check_random_device_valid(const std::string &token) {
     50   std::random_device r(token);
     51 }
     52 
     53 void check_random_device_invalid(const std::string &token) {
     54 #ifndef TEST_HAS_NO_EXCEPTIONS
     55   try {
     56     std::random_device r(token);
     57     LIBCPP_ASSERT(false);
     58   } catch (const std::system_error&) {
     59   }
     60 #else
     61   ((void)token);
     62 #endif
     63 }
     64 
     65 
     66 int main() {
     67   {
     68     std::random_device r;
     69   }
     70   {
     71     std::string token = "wrong file";
     72     check_random_device_invalid(token);
     73   }
     74   {
     75     std::string token = "/dev/urandom";
     76     if (is_valid_random_device(token))
     77       check_random_device_valid(token);
     78     else
     79       check_random_device_invalid(token);
     80   }
     81   {
     82     std::string token = "/dev/random";
     83     if (is_valid_random_device(token))
     84       check_random_device_valid(token);
     85     else
     86       check_random_device_invalid(token);
     87   }
     88 #if !defined(_WIN32)
     89 // Test that random_device(const string&) properly handles getting
     90 // a file descriptor with the value '0'. Do this by closing the standard
     91 // streams so that the descriptor '0' is available.
     92   {
     93     int ec;
     94     ec = close(STDIN_FILENO);
     95     assert(!ec);
     96     ec = close(STDOUT_FILENO);
     97     assert(!ec);
     98     ec = close(STDERR_FILENO);
     99     assert(!ec);
    100     std::random_device r;
    101   }
    102 #endif // !defined(_WIN32)
    103 }
    104