Add memfd_create(2) and mlock2(2).

These are old enough now that the latest devices will have kernels that
support them.

Also add basic doc comments to <sys/mman.h>.

Test: treehugger
Change-Id: I1b5ff5db0b6270f5c374287cac1d6a751a0259f5
diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp
index 0b98198..e403ea5 100644
--- a/tests/sys_mman_test.cpp
+++ b/tests/sys_mman_test.cpp
@@ -230,7 +230,10 @@
 TEST(sys_mman, mremap_PTRDIFF_MAX) {
   void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   ASSERT_NE(MAP_FAILED, map);
+
   ASSERT_EQ(MAP_FAILED, mremap(map, PAGE_SIZE, kHuge, MREMAP_MAYMOVE));
+
+  ASSERT_EQ(0, munmap(map, PAGE_SIZE));
 }
 
 TEST(sys_mman, mmap_bug_27265969) {
@@ -239,3 +242,61 @@
   // Some kernels had bugs that would cause segfaults here...
   __builtin___clear_cache(base, base + (PAGE_SIZE * 2));
 }
+
+TEST(sys_mman, mlock) {
+  void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_NE(MAP_FAILED, map);
+
+  // Not really anything we can assert about this.
+  mlock(map, PAGE_SIZE);
+
+  ASSERT_EQ(0, munmap(map, PAGE_SIZE));
+}
+
+TEST(sys_mman, mlock2) {
+#if defined(__GLIBC__)
+  GTEST_SKIP() << "needs glibc 2.27";
+#else
+  void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_NE(MAP_FAILED, map);
+
+  // Not really anything we can assert about this.
+  mlock2(map, PAGE_SIZE, MLOCK_ONFAULT);
+
+  ASSERT_EQ(0, munmap(map, PAGE_SIZE));
+#endif
+}
+
+TEST(sys_mman, memfd_create) {
+#if defined(__GLIBC__)
+  GTEST_SKIP() << "needs glibc 2.27";
+#else
+  // Is the MFD_CLOEXEC flag obeyed?
+  errno = 0;
+  int fd = memfd_create("doesn't matter", 0);
+  if (fd == -1) {
+    ASSERT_EQ(ENOSYS, errno);
+    GTEST_SKIP() << "no memfd_create available";
+  }
+  int f = fcntl(fd, F_GETFD);
+  ASSERT_NE(-1, f);
+  ASSERT_FALSE(f & FD_CLOEXEC);
+  close(fd);
+
+  errno = 0;
+  fd = memfd_create("doesn't matter", MFD_CLOEXEC);
+  f = fcntl(fd, F_GETFD);
+  ASSERT_NE(-1, f);
+  ASSERT_TRUE(f & FD_CLOEXEC);
+
+  // Can we read and write?
+  std::string expected("hello, world!");
+  ASSERT_TRUE(android::base::WriteStringToFd(expected, fd));
+  ASSERT_EQ(0, lseek(fd, 0, SEEK_SET));
+  std::string actual;
+  ASSERT_TRUE(android::base::ReadFdToString(fd, &actual));
+  ASSERT_EQ(expected, actual);
+
+  close(fd);
+#endif
+}