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 bugs.llvm.org/PR20183 10 // 11 // XFAIL: with_system_cxx_lib=macosx10.11 12 // XFAIL: with_system_cxx_lib=macosx10.10 13 // XFAIL: with_system_cxx_lib=macosx10.9 14 15 // UNSUPPORTED: libcpp-has-no-random-device 16 17 // <random> 18 19 // class random_device; 20 21 // explicit random_device(const string& token = implementation-defined); // before C++20 22 // random_device() : random_device(implementation-defined) {} // C++20 23 // explicit random_device(const string& token); // C++20 24 25 // For the following ctors, the standard states: "The semantics and default 26 // value of the token parameter are implementation-defined". Implementations 27 // therefore aren't required to accept any string, but the default shouldn't 28 // throw. 29 30 #include <random> 31 #include <system_error> 32 #include <cassert> 33 34 #if !defined(_WIN32) 35 #include <unistd.h> 36 #endif 37 38 #include "test_macros.h" 39 #if TEST_STD_VER >= 11 40 #include "test_convertible.h" 41 #endif 42 43 bool is_valid_random_device(const std::string &token) { 44 #if defined(_LIBCPP_USING_DEV_RANDOM) 45 // Not an exhaustive list: they're the only tokens that are tested below. 46 return token == "/dev/urandom" || token == "/dev/random"; 47 #else 48 return token == "/dev/urandom"; 49 #endif 50 } 51 52 void check_random_device_valid(const std::string &token) { 53 std::random_device r(token); 54 } 55 56 void check_random_device_invalid(const std::string &token) { 57 #ifndef TEST_HAS_NO_EXCEPTIONS 58 try { 59 std::random_device r(token); 60 LIBCPP_ASSERT(false); 61 } catch (const std::system_error&) { 62 } 63 #else 64 ((void)token); 65 #endif 66 } 67 68 int main(int, char**) { 69 { 70 std::random_device r; 71 } 72 { 73 std::string token = "wrong file"; 74 check_random_device_invalid(token); 75 } 76 { 77 std::string token = "/dev/urandom"; 78 if (is_valid_random_device(token)) 79 check_random_device_valid(token); 80 else 81 check_random_device_invalid(token); 82 } 83 { 84 std::string token = "/dev/random"; 85 if (is_valid_random_device(token)) 86 check_random_device_valid(token); 87 else 88 check_random_device_invalid(token); 89 } 90 #if !defined(_WIN32) 91 // Test that random_device(const string&) properly handles getting 92 // a file descriptor with the value '0'. Do this by closing the standard 93 // streams so that the descriptor '0' is available. 94 { 95 int ec; 96 ec = close(STDIN_FILENO); 97 assert(!ec); 98 ec = close(STDOUT_FILENO); 99 assert(!ec); 100 ec = close(STDERR_FILENO); 101 assert(!ec); 102 std::random_device r; 103 } 104 #endif // !defined(_WIN32) 105 106 #if TEST_STD_VER >= 11 107 static_assert(test_convertible<std::random_device>(), ""); 108 #endif 109 110 return 0; 111 } 112