Browse Source

LibCore/System: Add anon_create syscall wrapper

This wrapper is particularly helpful as we use a combination of similar
syscalls on Linux to simulate the behavior of the Serenity-exclusive
anon_create syscall. Users therefore won't have to worry about the
platform anymore :^)
kleines Filmröllchen 3 years ago
parent
commit
cf1f58d51c
2 changed files with 34 additions and 0 deletions
  1. 33 0
      Userland/Libraries/LibCore/System.cpp
  2. 1 0
      Userland/Libraries/LibCore/System.h

+ 33 - 0
Userland/Libraries/LibCore/System.cpp

@@ -7,6 +7,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <AK/StdLibExtras.h>
 #include <AK/String.h>
 #include <AK/Vector.h>
 #include <LibCore/System.h>
@@ -24,6 +25,16 @@
 #    include <serenity.h>
 #endif
 
+#if defined(__linux__) && !defined(MFD_CLOEXEC)
+#    include <linux/memfd.h>
+#    include <sys/syscall.h>
+
+static int memfd_create(const char* name, unsigned int flags)
+{
+    return syscall(SYS_memfd_create, name, flags);
+}
+#endif
+
 #define HANDLE_SYSCALL_RETURN_VALUE(syscall_name, rc, success_value) \
     if ((rc) < 0) {                                                  \
         return Error::from_syscall(syscall_name, rc);                \
@@ -245,6 +256,28 @@ ErrorOr<void> munmap(void* address, size_t size)
     return {};
 }
 
+ErrorOr<int> anon_create([[maybe_unused]] size_t size, [[maybe_unused]] int options)
+{
+    int fd = -1;
+#if defined(__serenity__)
+    fd = ::anon_create(round_up_to_power_of_two(size, PAGE_SIZE), options);
+#elif defined(__linux__)
+    // FIXME: Support more options on Linux.
+    auto linux_options = ((options & O_CLOEXEC) > 0) ? MFD_CLOEXEC : 0;
+    fd = memfd_create("", linux_options);
+    if (fd < 0)
+        return Error::from_errno(errno);
+    if (::ftruncate(fd, size) < 0) {
+        auto saved_errno = errno;
+        TRY(close(fd));
+        return Error::from_errno(saved_errno);
+    }
+#endif
+    if (fd < 0)
+        return Error::from_errno(errno);
+    return fd;
+}
+
 ErrorOr<int> open(StringView path, int options, ...)
 {
     if (!path.characters_without_null_termination())

+ 1 - 0
Userland/Libraries/LibCore/System.h

@@ -64,6 +64,7 @@ ErrorOr<struct stat> fstat(int fd);
 ErrorOr<int> fcntl(int fd, int command, ...);
 ErrorOr<void*> mmap(void* address, size_t, int protection, int flags, int fd, off_t, size_t alignment = 0, StringView name = {});
 ErrorOr<void> munmap(void* address, size_t);
+ErrorOr<int> anon_create(size_t size, int options);
 ErrorOr<int> open(StringView path, int options, ...);
 ErrorOr<void> close(int fd);
 ErrorOr<void> ftruncate(int fd, off_t length);