Export of internal Abseil changes

--
2c81c02d2b68303134e777f31921679ab87a2639 by Derek Mauro <dmauro@google.com>:

Use getentropy() to get seed material when using glibc >= 2.25

getentropy() uses the getrandom syscall on Linux to avoid file descriptors.
It is never interputed (EINTR) and uses the same source as /dev/urandom.
https://man7.org/linux/man-pages/man3/getentropy.3.html

getrandom has been in the Linux since kernel 3.17
When unavailable (ENOSYS), fallback to /dev/urandom.

PiperOrigin-RevId: 376962620

--
81cd41372a04eda400a2e3be53c239c0dac6bdf3 by Abseil Team <absl-team@google.com>:

Make FunctionRef no longer have -Wdeprecated-copy warnings from Clang by
defaulting the copy constructor.  This is needed because the assignment
operator is deleted.

Fixes #948

PiperOrigin-RevId: 376928548
GitOrigin-RevId: 2c81c02d2b68303134e777f31921679ab87a2639
Change-Id: I0abb18052ffff5dd1448f0b68edbb668045335f0
diff --git a/absl/functional/function_ref.h b/absl/functional/function_ref.h
index 6e03ac2..5790a65 100644
--- a/absl/functional/function_ref.h
+++ b/absl/functional/function_ref.h
@@ -122,6 +122,7 @@
   // To help prevent subtle lifetime bugs, FunctionRef is not assignable.
   // Typically, it should only be used as an argument type.
   FunctionRef& operator=(const FunctionRef& rhs) = delete;
+  FunctionRef(const FunctionRef& rhs) = default;
 
   // Call the underlying object.
   R operator()(Args... args) const {
diff --git a/absl/random/internal/seed_material.cc b/absl/random/internal/seed_material.cc
index 4d38a57..0fcba50 100644
--- a/absl/random/internal/seed_material.cc
+++ b/absl/random/internal/seed_material.cc
@@ -50,6 +50,12 @@
 
 #endif
 
+#if defined(__GLIBC__) && \
+    (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
+// glibc >= 2.25 has getentropy()
+#define ABSL_RANDOM_USE_GET_ENTROPY 1
+#endif
+
 #if defined(ABSL_RANDOM_USE_BCRYPT)
 #include <bcrypt.h>
 
@@ -122,8 +128,29 @@
 
 #else
 
+#if defined(ABSL_RANDOM_USE_GET_ENTROPY)
+// On *nix, use getentropy() if supported. Note that libc may support
+// getentropy(), but the kernel may not, in which case this function will return
+// false.
+bool ReadSeedMaterialFromGetEntropy(absl::Span<uint32_t> values) {
+  auto buffer = reinterpret_cast<uint8_t*>(values.data());
+  size_t buffer_size = sizeof(uint32_t) * values.size();
+  while (buffer_size > 0) {
+    // getentropy() has a maximum permitted length of 256.
+    size_t to_read = std::min<size_t>(buffer_size, 256);
+    int result = getentropy(buffer, to_read);
+    if (result < 0) {
+      return false;
+    }
+    buffer += to_read;
+    buffer_size -= to_read;
+  }
+  return true;
+}
+#endif  // defined(ABSL_RANDOM_GETENTROPY)
+
 // On *nix, read entropy from /dev/urandom.
-bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
+bool ReadSeedMaterialFromDevURandom(absl::Span<uint32_t> values) {
   const char kEntropyFile[] = "/dev/urandom";
 
   auto buffer = reinterpret_cast<uint8_t*>(values.data());
@@ -150,6 +177,17 @@
   return success;
 }
 
+bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
+#if defined(ABSL_RANDOM_USE_GET_ENTROPY)
+  if (ReadSeedMaterialFromGetEntropy(values)) {
+    return true;
+  }
+#endif
+  // Libc may support getentropy, but the kernel may not, so we still have
+  // to fallback to ReadSeedMaterialFromDevURandom().
+  return ReadSeedMaterialFromDevURandom(values);
+}
+
 #endif
 
 }  // namespace