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];