1//
2// Copyright (c) 2018 Andrey Semashev
3//
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at
6// https://www.boost.org/LICENSE_1_0.txt)
7//
8// getrandom() capable platforms
9//
10
11#include <boost/config.hpp>
12#include <boost/throw_exception.hpp>
13#include <boost/predef/library/c/gnu.h>
14#include <cerrno>
15#include <cstddef>
16
17#if !defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM) && !defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_DISABLE_LIBC_WRAPPER)
18#if BOOST_LIB_C_GNU >= BOOST_VERSION_NUMBER(2, 25, 0)
19#define BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER
20#elif defined(__has_include)
21#if __has_include(<sys/random.h>)
22#define BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER
23#endif
24#endif
25#endif // !defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM) && !defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_DISABLE_LIBC_WRAPPER)
26
27#if defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER)
28#include <sys/random.h>
29#else
30#include <stddef.h> // ssize_t
31#endif
32
33namespace boost {
34namespace uuids {
35namespace detail {
36
37class random_provider_base
38{
39public:
40 //! Obtain entropy and place it into a memory location
41 //! \param[in] buf the location to write entropy
42 //! \param[in] siz the number of bytes to acquire
43 void get_random_bytes(void *buf, std::size_t siz)
44 {
45 std::size_t offset = 0;
46 while (offset < siz)
47 {
48 ssize_t sz = get_random(buf: static_cast< char* >(buf) + offset, size: siz - offset, flags: 0u);
49
50 if (BOOST_UNLIKELY(sz < 0))
51 {
52 int err = errno;
53 if (err == EINTR)
54 continue;
55 BOOST_THROW_EXCEPTION(entropy_error(err, "getrandom"));
56 }
57
58 offset += sz;
59 }
60 }
61
62private:
63 static ssize_t get_random(void *buf, std::size_t size, unsigned int flags)
64 {
65#if defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM)
66 return BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM(buf, size, flags);
67#elif defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER)
68 return ::getrandom(buffer: buf, length: size, flags: flags);
69#else
70 return ::syscall(SYS_getrandom, buf, size, flags);
71#endif
72 }
73};
74
75} // detail
76} // uuids
77} // boost
78

source code of boost/libs/uuid/include/boost/uuid/detail/random_provider_getrandom.ipp