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