diff options
author | JF Bastien <jfb@google.com> | 2014-12-01 19:19:55 +0000 |
---|---|---|
committer | JF Bastien <jfb@google.com> | 2014-12-01 19:19:55 +0000 |
commit | 57148cbcbdad689080c2db7681b0e2bfc952d3d8 (patch) | |
tree | 06309cad9ea035ce65c7fd204d62539d6055e0a0 /libcxx/src | |
parent | 973b3612e49cb527ed89d7d06f630c40264c2ea0 (diff) | |
download | bcm5719-llvm-57148cbcbdad689080c2db7681b0e2bfc952d3d8.tar.gz bcm5719-llvm-57148cbcbdad689080c2db7681b0e2bfc952d3d8.zip |
libc++: add NaCl and PNaCl support for std::random_device
Summary:
The NaCl sandbox doesn't allow opening files under /dev, but it offers an API which provides the same capabilities. This is the same random device emulation that nacl_io performs for POSIX support, but nacl_io is an optional library so libc++ can't assume that device emulation will be performed. Note that NaCl only supports /dev/urandom, not /dev/random.
This patch also cleans up some of the preprocessor #endif, and fixes the test for Win32 (it accepts any token, and would therefore never throw regardless of the token provided).
Test Plan: ninja check-libcxx
Reviewers: dschuff, mclow.lists, danalbert
Subscribers: jfb, cfe-commits
Differential Revision: http://reviews.llvm.org/D6442
llvm-svn: 223068
Diffstat (limited to 'libcxx/src')
-rw-r--r-- | libcxx/src/random.cpp | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/libcxx/src/random.cpp b/libcxx/src/random.cpp index 86017ef0d46..15ed65b58cf 100644 --- a/libcxx/src/random.cpp +++ b/libcxx/src/random.cpp @@ -11,23 +11,27 @@ // Must be defined before including stdlib.h to enable rand_s(). #define _CRT_RAND_S #include <stdio.h> -#endif +#endif // defined(_WIN32) #include "random" #include "system_error" -#ifdef __sun__ +#if defined(__sun__) #define rename solaris_headers_are_broken -#endif +#endif // defined(__sun__) #if !defined(_WIN32) #include <fcntl.h> #include <unistd.h> -#endif // defined(_WIN32) +#endif // !defined(_WIN32) #include <errno.h> +#if defined(_LIBCPP_USING_NACL_RANDOM) +#include <nacl/nacl_random.h> +#endif // defined(_LIBCPP_USING_NACL_RANDOM) _LIBCPP_BEGIN_NAMESPACE_STD #if defined(_WIN32) + random_device::random_device(const string&) { } @@ -45,7 +49,39 @@ random_device::operator()() __throw_system_error(err, "random_device rand_s failed."); return r; } -#else + +#elif defined(_LIBCPP_USING_NACL_RANDOM) + +random_device::random_device(const string& __token) +{ + if (__token != "/dev/urandom") + __throw_system_error(ENOENT, ("random device not supported " + __token).c_str()); + int error = nacl_secure_random_init(); + if (error) + __throw_system_error(error, ("random device failed to open " + __token).c_str()); +} + +random_device::~random_device() +{ +} + +unsigned +random_device::operator()() +{ + unsigned r; + size_t n = sizeof(r); + char* p = reinterpret_cast<char*>(&r); + size_t bytes_written; + int error = nacl_secure_random(&r, n, &bytes_written); + if (error != 0) + __throw_system_error(error, "random_device failed getting bytes"); + else if (bytes_written != n) + __throw_runtime_error("random_device failed to obtain enough bytes"); + return r; +} + +#else // !defined(_WIN32) && !defined(_LIBCPP_USING_NACL_RANDOM) + random_device::random_device(const string& __token) : __f_(open(__token.c_str(), O_RDONLY)) { @@ -80,7 +116,8 @@ random_device::operator()() } return r; } -#endif // defined(_WIN32) + +#endif // defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM) double random_device::entropy() const _NOEXCEPT |