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 // <random>
11 
12 // class random_device;
13 
14 // explicit random_device(const string& token = implementation-defined);
15 
16 // For the following ctors, the standard states: "The semantics and default
17 // value of the token parameter are implementation-defined". Implementations
18 // therefore aren't required to accept any string, but the default shouldn't
19 // throw.
20 
21 #include <random>
22 #include <cassert>
23 #include <unistd.h>
24 
is_valid_random_device(const std::string & token)25 bool is_valid_random_device(const std::string &token) {
26 #if defined(_WIN32)
27   return true;
28 #elif defined(_LIBCPP_USING_NACL_RANDOM)
29   return token == "/dev/urandom";
30 #else  // !defined(_WIN32) && !defined(_LIBCPP_USING_NACL_RANDOM)
31   // Not an exhaustive list: they're the only tokens that are tested below.
32   return token == "/dev/urandom" || token == "/dev/random";
33 #endif // defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM)
34 }
35 
check_random_device_valid(const std::string & token)36 void check_random_device_valid(const std::string &token) {
37   std::random_device r(token);
38 }
39 
check_random_device_invalid(const std::string & token)40 void check_random_device_invalid(const std::string &token) {
41   try {
42     std::random_device r(token);
43     assert(false);
44   } catch (const std::system_error &e) {
45   }
46 }
47 
main()48 int main() {
49   { std::random_device r; }
50 
51   {
52     int ec;
53     ec = close(STDIN_FILENO);
54     assert(!ec);
55     ec = close(STDOUT_FILENO);
56     assert(!ec);
57     ec = close(STDERR_FILENO);
58     assert(!ec);
59     std::random_device r;
60   }
61 
62   {
63     std::string token = "wrong file";
64     if (is_valid_random_device(token))
65       check_random_device_valid(token);
66     else
67       check_random_device_invalid(token);
68   }
69 
70   {
71     std::string token = "/dev/urandom";
72     if (is_valid_random_device(token))
73       check_random_device_valid(token);
74     else
75       check_random_device_invalid(token);
76   }
77 
78   {
79     std::string token = "/dev/random";
80     if (is_valid_random_device(token))
81       check_random_device_valid(token);
82     else
83       check_random_device_invalid(token);
84   }
85 }
86