File indexing completed on 2025-01-18 09:53:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <boost/config.hpp>
0016 #include <boost/core/ignore_unused.hpp>
0017 #include <boost/move/core.hpp>
0018 #include <boost/throw_exception.hpp>
0019 #include <boost/uuid/entropy_error.hpp>
0020 #include <cerrno>
0021 #include <cstddef>
0022 #include <fcntl.h> // open
0023 #include <sys/stat.h>
0024 #include <sys/types.h>
0025 #if defined(BOOST_HAS_UNISTD_H)
0026 #include <unistd.h>
0027 #endif
0028
0029 #ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE
0030 #define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE ::close
0031 #endif
0032 #ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN
0033 #define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN ::open
0034 #endif
0035 #ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ
0036 #define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ ::read
0037 #endif
0038
0039 namespace boost {
0040 namespace uuids {
0041 namespace detail {
0042
0043 class random_provider_base
0044 {
0045 BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider_base)
0046
0047 public:
0048 random_provider_base()
0049 : fd_(-1)
0050 {
0051 int flags = O_RDONLY;
0052 #if defined(O_CLOEXEC)
0053 flags |= O_CLOEXEC;
0054 #endif
0055 fd_ = BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN("/dev/urandom", flags);
0056
0057 if (BOOST_UNLIKELY(-1 == fd_))
0058 {
0059 int err = errno;
0060 BOOST_THROW_EXCEPTION(entropy_error(err, "open /dev/urandom"));
0061 }
0062 }
0063
0064 random_provider_base(BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT : fd_(that.fd_)
0065 {
0066 that.fd_ = -1;
0067 }
0068
0069 random_provider_base& operator= (BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT
0070 {
0071 destroy();
0072 fd_ = that.fd_;
0073 that.fd_ = -1;
0074 return *this;
0075 }
0076
0077 ~random_provider_base() BOOST_NOEXCEPT
0078 {
0079 destroy();
0080 }
0081
0082
0083
0084
0085 void get_random_bytes(void *buf, std::size_t siz)
0086 {
0087 std::size_t offset = 0;
0088 while (offset < siz)
0089 {
0090 ssize_t sz = BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ(
0091 fd_, static_cast<char *>(buf) + offset, siz - offset);
0092
0093 if (BOOST_UNLIKELY(sz < 0))
0094 {
0095 int err = errno;
0096 if (err == EINTR)
0097 continue;
0098 BOOST_THROW_EXCEPTION(entropy_error(err, "read"));
0099 }
0100
0101 offset += sz;
0102 }
0103 }
0104
0105 private:
0106 void destroy() BOOST_NOEXCEPT
0107 {
0108 if (fd_ >= 0)
0109 {
0110 boost::ignore_unused(BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE(fd_));
0111 }
0112 }
0113
0114 private:
0115 int fd_;
0116 };
0117
0118 }
0119 }
0120 }