/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.28.0/src/sys/memfd.rs
Line | Count | Source |
1 | | //! Interfaces for managing memory-backed files. |
2 | | |
3 | | use cfg_if::cfg_if; |
4 | | use std::os::unix::io::{FromRawFd, OwnedFd, RawFd}; |
5 | | |
6 | | use crate::errno::Errno; |
7 | | use crate::Result; |
8 | | use std::ffi::CStr; |
9 | | |
10 | | libc_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 | | /// Anonymous file will be created using huge pages. It should be safe now to |
33 | | /// combine with [`MFD_ALLOW_SEALING`] too. |
34 | | /// However, despite its presence, on FreeBSD it is unimplemented for now (ENOSYS). |
35 | | /// |
36 | | /// See also the hugetlb filesystem in [`memfd_create(2)`]. |
37 | | /// |
38 | | /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html |
39 | | #[cfg(linux_android)] |
40 | | MFD_HUGETLB; |
41 | | /// Following are to be used with [`MFD_HUGETLB`], indicating the desired hugetlb size. |
42 | | /// |
43 | | /// See also the hugetlb filesystem in [`memfd_create(2)`]. |
44 | | /// |
45 | | /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html |
46 | | #[cfg(linux_android)] |
47 | | MFD_HUGE_1MB; |
48 | | /// hugetlb size of 2MB. |
49 | | #[cfg(linux_android)] |
50 | | MFD_HUGE_2MB; |
51 | | /// hugetlb size of 8MB. |
52 | | #[cfg(linux_android)] |
53 | | MFD_HUGE_8MB; |
54 | | /// hugetlb size of 16MB. |
55 | | #[cfg(linux_android)] |
56 | | MFD_HUGE_16MB; |
57 | | /// hugetlb size of 32MB. |
58 | | #[cfg(linux_android)] |
59 | | MFD_HUGE_32MB; |
60 | | /// hugetlb size of 256MB. |
61 | | #[cfg(linux_android)] |
62 | | MFD_HUGE_256MB; |
63 | | /// hugetlb size of 512MB. |
64 | | #[cfg(linux_android)] |
65 | | MFD_HUGE_512MB; |
66 | | /// hugetlb size of 1GB. |
67 | | #[cfg(linux_android)] |
68 | | MFD_HUGE_1GB; |
69 | | /// hugetlb size of 2GB. |
70 | | #[cfg(linux_android)] |
71 | | MFD_HUGE_2GB; |
72 | | /// hugetlb size of 16GB. |
73 | | #[cfg(linux_android)] |
74 | | MFD_HUGE_16GB; |
75 | | } |
76 | | ); |
77 | | |
78 | | /// Creates an anonymous file that lives in memory, and return a file-descriptor to it. |
79 | | /// |
80 | | /// The file behaves like a regular file, and so can be modified, truncated, memory-mapped, and so on. |
81 | | /// However, unlike a regular file, it lives in RAM and has a volatile backing storage. |
82 | | /// |
83 | | /// For more information, see [`memfd_create(2)`]. |
84 | | /// |
85 | | /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html |
86 | | #[inline] // Delays codegen, preventing linker errors with dylibs and --no-allow-shlib-undefined |
87 | 0 | pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<OwnedFd> { |
88 | 0 | let res = unsafe { |
89 | | cfg_if! { |
90 | | if #[cfg(all( |
91 | | // Android does not have a memfd_create symbol |
92 | | not(target_os = "android"), |
93 | | any( |
94 | | target_os = "freebsd", |
95 | | // If the OS is Linux, gnu and musl expose a memfd_create symbol but not uclibc |
96 | | target_env = "gnu", |
97 | | target_env = "musl", |
98 | | )))] |
99 | | { |
100 | 0 | libc::memfd_create(name.as_ptr(), flags.bits()) |
101 | | } else { |
102 | | libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits()) |
103 | | } |
104 | | } |
105 | | }; |
106 | | |
107 | 0 | Errno::result(res).map(|r| unsafe { OwnedFd::from_raw_fd(r as RawFd) }) |
108 | 0 | } |