Implement SharedFD::MemfdCreate.

This makes it convenient to create SharedFDs for in-memory-only files.

Android currently has host prebuilts of glibc 2.15 and 2.17, but
memfd_create was only added in glibc 2.27. It was defined in Linux 3.17,
so we consider it safe to use the low-level arbitrary syscall wrapper.

Test: N/A
Change-Id: Id7de8f89537b2b8d0ed9b171bfb37bf770596386
diff --git a/common/libs/fs/shared_fd.cpp b/common/libs/fs/shared_fd.cpp
index 2f6d100..b85cf7c 100644
--- a/common/libs/fs/shared_fd.cpp
+++ b/common/libs/fs/shared_fd.cpp
@@ -17,6 +17,8 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
 #include <cstddef>
 #include <errno.h>
 #include <fcntl.h>
@@ -52,6 +54,34 @@
     }
   }
 }
+
+/*
+ * Android currently has host prebuilts of glibc 2.15 and 2.17, but
+ * memfd_create was only added in glibc 2.27. It was defined in Linux 3.17,
+ * so we consider it safe to use the low-level arbitrary syscall wrapper.
+ */
+#ifndef __NR_memfd_create
+# if defined(__x86_64__)
+#  define __NR_memfd_create 319
+# elif defined(__i386__)
+#  define __NR_memfd_create 356
+# elif defined(__aarch64__)
+#  define __NR_memfd_create 279
+# else
+/* No interest in other architectures. */
+#  error "Unknown architecture."
+# endif
+#endif
+
+int memfd_create_wrapper(const char* name, unsigned int flags) {
+#ifdef CUTTLEFISH_HOST
+  // TODO(schuffelen): Use memfd_create with a newer host libc.
+  return syscall(__NR_memfd_create, name, flags);
+#else
+  return memfd_create(name, flags);
+#endif
+}
+
 }  // namespace
 
 namespace cvd {
@@ -256,6 +286,12 @@
   return std::shared_ptr<FileInstance>(new FileInstance(fd, errno));
 }
 
+SharedFD SharedFD::MemfdCreate(const char* name, unsigned int flags) {
+  int fd = memfd_create_wrapper(name, flags);
+  int error_num = errno;
+  return std::shared_ptr<FileInstance>(new FileInstance(fd, error_num));
+}
+
 bool SharedFD::SocketPair(int domain, int type, int protocol,
                           SharedFD* fd0, SharedFD* fd1) {
   int fds[2];