rustix/backend/libc/mm/
syscalls.rs1#[cfg(not(target_os = "redox"))]
4use super::types::Advice;
5#[cfg(any(linux_kernel, freebsdlike, netbsdlike))]
6use super::types::MlockAllFlags;
7#[cfg(any(target_os = "emscripten", target_os = "linux"))]
8use super::types::MremapFlags;
9use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags};
10#[cfg(linux_kernel)]
11use super::types::{MlockFlags, UserfaultfdFlags};
12use crate::backend::c;
13#[cfg(linux_kernel)]
14use crate::backend::conv::ret_owned_fd;
15use crate::backend::conv::{borrowed_fd, no_fd, ret};
16use crate::fd::BorrowedFd;
17#[cfg(linux_kernel)]
18use crate::fd::OwnedFd;
19use crate::io;
20
21#[cfg(not(target_os = "redox"))]
22pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> {
23 #[cfg(target_os = "linux")]
27 if let Advice::LinuxDontNeed = advice {
28 return unsafe { ret(c::madvise(addr, len, c::MADV_DONTNEED)) };
29 }
30
31 #[cfg(not(target_os = "android"))]
32 {
33 let err = unsafe { c::posix_madvise(addr, len, advice as c::c_int) };
34
35 if err == 0 {
37 Ok(())
38 } else {
39 Err(io::Errno(err))
40 }
41 }
42
43 #[cfg(target_os = "android")]
44 {
45 if let Advice::DontNeed = advice {
46 Ok(())
49 } else {
50 unsafe { ret(c::madvise(addr, len, advice as c::c_int)) }
51 }
52 }
53}
54
55pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> {
56 let err = c::msync(addr, len, bitflags_bits!(flags));
57
58 if err == 0 {
60 Ok(())
61 } else {
62 Err(io::Errno(err))
63 }
64}
65
66pub(crate) unsafe fn mmap(
71 ptr: *mut c::c_void,
72 len: usize,
73 prot: ProtFlags,
74 flags: MapFlags,
75 fd: BorrowedFd<'_>,
76 offset: u64,
77) -> io::Result<*mut c::c_void> {
78 let res = c::mmap(
79 ptr,
80 len,
81 bitflags_bits!(prot),
82 bitflags_bits!(flags),
83 borrowed_fd(fd),
84 offset as i64,
85 );
86 if res == c::MAP_FAILED {
87 Err(io::Errno::last_os_error())
88 } else {
89 Ok(res)
90 }
91}
92
93pub(crate) unsafe fn mmap_anonymous(
98 ptr: *mut c::c_void,
99 len: usize,
100 prot: ProtFlags,
101 flags: MapFlags,
102) -> io::Result<*mut c::c_void> {
103 let res = c::mmap(
104 ptr,
105 len,
106 bitflags_bits!(prot),
107 bitflags_bits!(flags | MapFlags::from_bits_retain(bitcast!(c::MAP_ANONYMOUS))),
108 no_fd(),
109 0,
110 );
111 if res == c::MAP_FAILED {
112 Err(io::Errno::last_os_error())
113 } else {
114 Ok(res)
115 }
116}
117
118pub(crate) unsafe fn mprotect(
119 ptr: *mut c::c_void,
120 len: usize,
121 flags: MprotectFlags,
122) -> io::Result<()> {
123 ret(c::mprotect(ptr, len, bitflags_bits!(flags)))
124}
125
126pub(crate) unsafe fn munmap(ptr: *mut c::c_void, len: usize) -> io::Result<()> {
127 ret(c::munmap(ptr, len))
128}
129
130#[cfg(any(target_os = "emscripten", target_os = "linux"))]
135pub(crate) unsafe fn mremap(
136 old_address: *mut c::c_void,
137 old_size: usize,
138 new_size: usize,
139 flags: MremapFlags,
140) -> io::Result<*mut c::c_void> {
141 let res = c::mremap(old_address, old_size, new_size, bitflags_bits!(flags));
142 if res == c::MAP_FAILED {
143 Err(io::Errno::last_os_error())
144 } else {
145 Ok(res)
146 }
147}
148
149#[cfg(any(target_os = "emscripten", target_os = "linux"))]
155pub(crate) unsafe fn mremap_fixed(
156 old_address: *mut c::c_void,
157 old_size: usize,
158 new_size: usize,
159 flags: MremapFlags,
160 new_address: *mut c::c_void,
161) -> io::Result<*mut c::c_void> {
162 let res = c::mremap(
163 old_address,
164 old_size,
165 new_size,
166 bitflags_bits!(flags | MremapFlags::from_bits_retain(bitcast!(c::MAP_FIXED))),
167 new_address,
168 );
169 if res == c::MAP_FAILED {
170 Err(io::Errno::last_os_error())
171 } else {
172 Ok(res)
173 }
174}
175
176#[inline]
181pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> {
182 ret(c::mlock(addr, length))
183}
184
185#[cfg(linux_kernel)]
190#[inline]
191pub(crate) unsafe fn mlock_with(
192 addr: *mut c::c_void,
193 length: usize,
194 flags: MlockFlags,
195) -> io::Result<()> {
196 weak_or_syscall! {
197 fn mlock2(
198 addr: *const c::c_void,
199 len: c::size_t,
200 flags: c::c_int
201 ) via SYS_mlock2 -> c::c_int
202 }
203
204 ret(mlock2(addr, length, bitflags_bits!(flags)))
205}
206
207#[inline]
212pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> {
213 ret(c::munlock(addr, length))
214}
215
216#[cfg(linux_kernel)]
217pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> {
218 syscall! {
219 fn userfaultfd(
220 flags: c::c_int
221 ) via SYS_userfaultfd -> c::c_int
222 }
223 ret_owned_fd(userfaultfd(bitflags_bits!(flags)))
224}
225
226#[inline]
234#[cfg(any(linux_kernel, freebsdlike, netbsdlike))]
235pub(crate) fn mlockall(flags: MlockAllFlags) -> io::Result<()> {
236 unsafe { ret(c::mlockall(bitflags_bits!(flags))) }
237}
238
239#[inline]
241#[cfg(any(linux_kernel, freebsdlike, netbsdlike))]
242pub(crate) fn munlockall() -> io::Result<()> {
243 unsafe { ret(c::munlockall()) }
244}