diff --git a/osbuild/util/linux.py b/osbuild/util/linux.py index d09af8fc..a26d62bb 100644 --- a/osbuild/util/linux.py +++ b/osbuild/util/linux.py @@ -490,6 +490,29 @@ class Libc: setattr(proto, "errcheck", self._errcheck_errno) setattr(proto, "__name__", "futimens") self.futimens = proto + # prototype: _memfd_create() (takes a byte type name) + # (can be removed once we move to python3.8) + proto = ctypes.CFUNCTYPE( + ctypes.c_int, # restype (return type) + ctypes.c_char_p, + ctypes.c_uint, + use_errno=True, + )( + ("memfd_create", self._lib), + ( + (1, "name"), + (1, "flags", 0), + ), + ) + setattr(proto, "errcheck", self._errcheck_errno) + setattr(proto, "__name__", "memfd_create") + self._memfd_create = proto + + # (can be removed once we move to python3.8) + def memfd_create(self, name: str, flags: int = 0) -> int: + """ create an anonymous file """ + char_p_name = name.encode() + return self._memfd_create(char_p_name, flags) @staticmethod def make() -> "Libc": diff --git a/test/mod/test_util_linux.py b/test/mod/test_util_linux.py index 518a4bfa..b77bc8dc 100644 --- a/test/mod/test_util_linux.py +++ b/test/mod/test_util_linux.py @@ -187,6 +187,7 @@ def test_libc(): assert libc0.RENAME_NOREPLACE assert libc0.RENAME_WHITEOUT assert libc0.renameat2 + assert libc0.memfd_create def test_libc_renameat2_errcheck(): @@ -226,6 +227,23 @@ def test_libc_renameat2_exchange(tmpdir): assert f.read() == "foo" +def test_libc_memfd_create_errcheck(): + libc = linux.Libc.default() + with pytest.raises(OSError) as exc: + libc.memfd_create("foo", -1) + assert "Invalid argument" in str(exc.value) + + +def test_libc_memfd_create(): + libc = linux.Libc.default() + fd = libc.memfd_create("foo", 0) + os.write(fd, b"file content") + fd2 = os.dup(fd) + os.close(fd) + os.lseek(fd2, 0, 0) + assert os.read(fd2, 4096) == b"file content" + + def test_proc_boot_id(): # # Test the `proc_boot_id()` function which reads the current boot-id