Add <sys/random.h>.

iOS 10 has <sys/random.h> with getentropy, glibc >= 2.25 has
<sys/random.h> with getentropy and getrandom. (glibc also pollutes
<unistd.h>, but that seems like a bad idea.)

Also, all supported devices now have kernels with the getrandom system
call.

We've had these available internally for a while, but it seems like the
time is ripe to expose them.

Bug: http://b/67014255
Test: ran tests
Change-Id: I76dde1e3a2d0bc82777eea437ac193f96964f138
diff --git a/tests/sys_random_test.cpp b/tests/sys_random_test.cpp
new file mode 100644
index 0000000..a25490c
--- /dev/null
+++ b/tests/sys_random_test.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// <sys/random.h> was only added as of glibc version 2.25.
+// Don't try to compile this code on older glibc versions.
+
+#include <sys/cdefs.h>
+#if defined(__BIONIC__)
+  #define HAVE_SYS_RANDOM 1
+#elif defined(__GLIBC_PREREQ)
+  #if __GLIBC_PREREQ(2, 25)
+    #define HAVE_SYS_RANDOM 1
+  #endif
+#endif
+
+
+#if defined(HAVE_SYS_RANDOM)
+#include <sys/random.h>
+#endif
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+TEST(sys_random, getentropy) {
+#if defined(HAVE_SYS_RANDOM)
+  char buf1[64];
+  char buf2[64];
+
+  ASSERT_EQ(0, getentropy(buf1, sizeof(buf1)));
+  ASSERT_EQ(0, getentropy(buf2, sizeof(buf2)));
+  ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getentropy_EFAULT) {
+#if defined(HAVE_SYS_RANDOM)
+  errno = 0;
+  ASSERT_EQ(-1, getentropy(nullptr, 1));
+  ASSERT_EQ(EFAULT, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getentropy_EIO) {
+#if defined(HAVE_SYS_RANDOM)
+  char buf[BUFSIZ];
+  static_assert(BUFSIZ > 256, "BUFSIZ <= 256!");
+
+  errno = 0;
+  ASSERT_EQ(-1, getentropy(buf, sizeof(buf)));
+  ASSERT_EQ(EIO, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom) {
+#if defined(HAVE_SYS_RANDOM)
+  if (getrandom(nullptr, 0, 0) == -1 && errno == ENOSYS) {
+    GTEST_LOG_(INFO) << "This test requires a >= 3.17 kernel with getrandom(2).\n";
+    return;
+  }
+
+  char buf1[64];
+  char buf2[64];
+
+  ASSERT_EQ(64, getrandom(buf1, sizeof(buf1), 0));
+  ASSERT_EQ(64, getrandom(buf2, sizeof(buf2), 0));
+  ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom_EFAULT) {
+#if defined(HAVE_SYS_RANDOM)
+  if (getrandom(nullptr, 0, 0) == -1 && errno == ENOSYS) {
+    GTEST_LOG_(INFO) << "This test requires a >= 3.17 kernel with getrandom(2).\n";
+    return;
+  }
+
+  errno = 0;
+  ASSERT_EQ(-1, getrandom(nullptr, 256, 0));
+  ASSERT_EQ(EFAULT, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom_EINVAL) {
+#if defined(HAVE_SYS_RANDOM)
+  if (getrandom(nullptr, 0, 0) == -1 && errno == ENOSYS) {
+    GTEST_LOG_(INFO) << "This test requires a >= 3.17 kernel with getrandom(2).\n";
+    return;
+  }
+
+  errno = 0;
+  char buf[64];
+  ASSERT_EQ(-1, getrandom(buf, sizeof(buf), ~0));
+  ASSERT_EQ(EINVAL, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}