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 <cassert>
24 #include <unistd.h>
25 
26 bool is_valid_random_device(const std::string &token) {
27 #if defined(_LIBCPP_USING_DEV_RANDOM)
28   // Not an exhaustive list: they're the only tokens that are tested below.
29   return token == "/dev/urandom" || token == "/dev/random";
30 #else
31   return token == "/dev/urandom";
32 #endif
33 }
34 
35 void check_random_device_valid(const std::string &token) {
36   std::random_device r(token);
37 }
38 
39 void check_random_device_invalid(const std::string &token) {
40   try {
41     std::random_device r(token);
42     assert(false);
43   } catch (const std::system_error &e) {
44   }
45 }
46 
47 int main() {
48   { std::random_device r; }
49 
50   {
51     int ec;
52     ec = close(STDIN_FILENO);
53     assert(!ec);
54     ec = close(STDOUT_FILENO);
55     assert(!ec);
56     ec = close(STDERR_FILENO);
57     assert(!ec);
58     std::random_device r;
59   }
60 
61   {
62     std::string token = "wrong file";
63     if (is_valid_random_device(token))
64       check_random_device_valid(token);
65     else
66       check_random_device_invalid(token);
67   }
68 
69   {
70     std::string token = "/dev/urandom";
71     if (is_valid_random_device(token))
72       check_random_device_valid(token);
73     else
74       check_random_device_invalid(token);
75   }
76 
77   {
78     std::string token = "/dev/random";
79     if (is_valid_random_device(token))
80       check_random_device_valid(token);
81     else
82       check_random_device_invalid(token);
83   }
84 }
85