diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp index 244a09a821..3d8d5bd1a7 100644 --- a/Userland/Libraries/LibCore/System.cpp +++ b/Userland/Libraries/LibCore/System.cpp @@ -7,6 +7,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -24,6 +25,16 @@ # include #endif +#if defined(__linux__) && !defined(MFD_CLOEXEC) +# include +# include + +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 munmap(void* address, size_t size) return {}; } +ErrorOr 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 open(StringView path, int options, ...) { if (!path.characters_without_null_termination()) diff --git a/Userland/Libraries/LibCore/System.h b/Userland/Libraries/LibCore/System.h index 1583e76fb8..0ccdb54b74 100644 --- a/Userland/Libraries/LibCore/System.h +++ b/Userland/Libraries/LibCore/System.h @@ -64,6 +64,7 @@ ErrorOr fstat(int fd); ErrorOr fcntl(int fd, int command, ...); ErrorOr mmap(void* address, size_t, int protection, int flags, int fd, off_t, size_t alignment = 0, StringView name = {}); ErrorOr munmap(void* address, size_t); +ErrorOr anon_create(size_t size, int options); ErrorOr open(StringView path, int options, ...); ErrorOr close(int fd); ErrorOr ftruncate(int fd, off_t length);