1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // XFAIL: libcpp-no-exceptions 11 // <random> 12 13 // class random_device; 14 15 // explicit random_device(const string& token = implementation-defined); 16 17 // For the following ctors, the standard states: "The semantics and default 18 // value of the token parameter are implementation-defined". Implementations 19 // therefore aren't required to accept any string, but the default shouldn't 20 // throw. 21 22 #include <random> 23 #include <system_error> 24 #include <cassert> 25 26 #if !defined(_WIN32) 27 #include <unistd.h> 28 #endif 29 30 #include "test_macros.h" 31 32 33 bool is_valid_random_device(const std::string &token) { 34 #if defined(_LIBCPP_USING_DEV_RANDOM) 35 // Not an exhaustive list: they're the only tokens that are tested below. 36 return token == "/dev/urandom" || token == "/dev/random"; 37 #else 38 return token == "/dev/urandom"; 39 #endif 40 } 41 42 void check_random_device_valid(const std::string &token) { 43 std::random_device r(token); 44 } 45 46 void check_random_device_invalid(const std::string &token) { 47 try { 48 std::random_device r(token); 49 LIBCPP_ASSERT(false); 50 } catch (const std::system_error&) { 51 } 52 } 53 54 55 int main() { 56 { 57 std::random_device r; 58 } 59 { 60 std::string token = "wrong file"; 61 check_random_device_invalid(token); 62 } 63 { 64 std::string token = "/dev/urandom"; 65 if (is_valid_random_device(token)) 66 check_random_device_valid(token); 67 else 68 check_random_device_invalid(token); 69 } 70 { 71 std::string token = "/dev/random"; 72 if (is_valid_random_device(token)) 73 check_random_device_valid(token); 74 else 75 check_random_device_invalid(token); 76 } 77 #if !defined(_WIN32) 78 // Test that random_device(const string&) properly handles getting 79 // a file descriptor with the value '0'. Do this by closing the standard 80 // streams so that the descriptor '0' is available. 81 { 82 int ec; 83 ec = close(STDIN_FILENO); 84 assert(!ec); 85 ec = close(STDOUT_FILENO); 86 assert(!ec); 87 ec = close(STDERR_FILENO); 88 assert(!ec); 89 std::random_device r; 90 } 91 #endif // !defined(_WIN32) 92 } 93