1//! Interfaces for managing memory-backed files. 2 3use cfg_if::cfg_if; 4use std::os::unix::io::RawFd; 5 6use crate::errno::Errno; 7use crate::Result; 8use std::ffi::CStr; 9 10libc_bitflags!( 11 /// Options that change the behavior of [`memfd_create`]. 12 pub struct MemFdCreateFlag: libc::c_uint { 13 /// Set the close-on-exec ([`FD_CLOEXEC`]) flag on the new file descriptor. 14 /// 15 /// By default, the new file descriptor is set to remain open across an [`execve`] 16 /// (the `FD_CLOEXEC` flag is initially disabled). This flag can be used to change 17 /// this default. The file offset is set to the beginning of the file (see [`lseek`]). 18 /// 19 /// See also the description of the `O_CLOEXEC` flag in [`open(2)`]. 20 /// 21 /// [`execve`]: crate::unistd::execve 22 /// [`lseek`]: crate::unistd::lseek 23 /// [`FD_CLOEXEC`]: crate::fcntl::FdFlag::FD_CLOEXEC 24 /// [`open(2)`]: https://man7.org/linux/man-pages/man2/open.2.html 25 MFD_CLOEXEC; 26 /// Allow sealing operations on this file. 27 /// 28 /// See also the file sealing notes given in [`memfd_create(2)`]. 29 /// 30 /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html 31 MFD_ALLOW_SEALING; 32 } 33); 34 35/// Creates an anonymous file that lives in memory, and return a file-descriptor to it. 36/// 37/// The file behaves like a regular file, and so can be modified, truncated, memory-mapped, and so on. 38/// However, unlike a regular file, it lives in RAM and has a volatile backing storage. 39/// 40/// For more information, see [`memfd_create(2)`]. 41/// 42/// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html 43pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<RawFd> { 44 let res = unsafe { 45 cfg_if! { 46 if #[cfg(all( 47 // Android does not have a memfd_create symbol 48 not(target_os = "android"), 49 any( 50 target_os = "freebsd", 51 // If the OS is Linux, gnu and musl expose a memfd_create symbol but not uclibc 52 target_env = "gnu", 53 target_env = "musl", 54 target_env = "ohos", 55 )))] 56 { 57 libc::memfd_create(name.as_ptr(), flags.bits()) 58 } else { 59 libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits()) 60 } 61 } 62 }; 63 64 Errno::result(res).map(|r| r as RawFd) 65} 66