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