1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // See https://llvm.org/PR20183 |
10 | // XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11}} |
11 | |
12 | // The behavior of std::random_device changed on Apple platforms with |
13 | // https://llvm.org/D116045. |
14 | // XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}} |
15 | |
16 | // UNSUPPORTED: no-random-device |
17 | |
18 | // <random> |
19 | |
20 | // class random_device; |
21 | |
22 | // explicit random_device(const string& token = implementation-defined); // before C++20 |
23 | // random_device() : random_device(implementation-defined) {} // C++20 |
24 | // explicit random_device(const string& token); // C++20 |
25 | |
26 | // For the following ctors, the standard states: "The semantics and default |
27 | // value of the token parameter are implementation-defined". Implementations |
28 | // therefore aren't required to accept any string, but the default shouldn't |
29 | // throw. |
30 | |
31 | #include <random> |
32 | #include <string> |
33 | #include <system_error> |
34 | #include <cassert> |
35 | |
36 | #if !defined(_WIN32) |
37 | #include <unistd.h> |
38 | #endif |
39 | |
40 | #include "test_macros.h" |
41 | #if TEST_STD_VER >= 11 |
42 | #include "test_convertible.h" |
43 | #endif |
44 | |
45 | void check_random_device_valid(const std::string &token) { |
46 | std::random_device r(token); |
47 | } |
48 | |
49 | void check_random_device_invalid(const std::string &token) { |
50 | #ifndef TEST_HAS_NO_EXCEPTIONS |
51 | try { |
52 | std::random_device r(token); |
53 | LIBCPP_ASSERT(false); |
54 | } catch (const std::system_error&) { |
55 | } |
56 | #else |
57 | ((void)token); |
58 | #endif |
59 | } |
60 | |
61 | int main(int, char**) { |
62 | { |
63 | std::random_device r; |
64 | (void)r; |
65 | } |
66 | // Check the validity of various tokens |
67 | { |
68 | #if defined(_LIBCPP_USING_ARC4_RANDOM) |
69 | check_random_device_valid("/dev/urandom" ); |
70 | check_random_device_valid("/dev/random" ); |
71 | check_random_device_valid("/dev/null" ); |
72 | check_random_device_valid("/dev/nonexistent" ); |
73 | check_random_device_valid("wrong file" ); |
74 | #elif defined(_LIBCPP_USING_DEV_RANDOM) |
75 | check_random_device_valid("/dev/urandom" ); |
76 | check_random_device_valid("/dev/random" ); |
77 | check_random_device_valid("/dev/null" ); |
78 | check_random_device_invalid("/dev/nonexistent" ); |
79 | check_random_device_invalid("wrong file" ); |
80 | #else |
81 | check_random_device_valid(token: "/dev/urandom" ); |
82 | check_random_device_invalid(token: "/dev/random" ); |
83 | check_random_device_invalid(token: "/dev/null" ); |
84 | check_random_device_invalid(token: "/dev/nonexistent" ); |
85 | check_random_device_invalid(token: "wrong file" ); |
86 | #endif |
87 | } |
88 | |
89 | #if !defined(_WIN32) |
90 | // Test that random_device(const string&) properly handles getting |
91 | // a file descriptor with the value '0'. Do this by closing the standard |
92 | // streams so that the descriptor '0' is available. |
93 | { |
94 | int ec; |
95 | ec = close(STDIN_FILENO); |
96 | assert(!ec); |
97 | ec = close(STDOUT_FILENO); |
98 | assert(!ec); |
99 | ec = close(STDERR_FILENO); |
100 | assert(!ec); |
101 | std::random_device r; |
102 | } |
103 | #endif // !defined(_WIN32) |
104 | |
105 | #if TEST_STD_VER >= 11 |
106 | static_assert(test_convertible<std::random_device>(), "" ); |
107 | #endif |
108 | |
109 | return 0; |
110 | } |
111 | |