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