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