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 // XFAIL: libcpp-no-exceptions
11 // <random>
12 
13 // class random_device;
14 
15 // explicit random_device(const string& token = implementation-defined);
16 
17 // For the following ctors, the standard states: "The semantics and default
18 // value of the token parameter are implementation-defined". Implementations
19 // therefore aren't required to accept any string, but the default shouldn't
20 // throw.
21 
22 #include <random>
23 #include <system_error>
24 #include <cassert>
25 #include <unistd.h>
26 
27 bool is_valid_random_device(const std::string &token) {
28 #if defined(_LIBCPP_USING_DEV_RANDOM)
29   // Not an exhaustive list: they're the only tokens that are tested below.
30   return token == "/dev/urandom" || token == "/dev/random";
31 #else
32   return token == "/dev/urandom";
33 #endif
34 }
35 
36 void check_random_device_valid(const std::string &token) {
37   std::random_device r(token);
38 }
39 
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 
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