1 //! libc syscalls supporting `rustix::mm`.
4 #[cfg(any(target_os = "android", target_os = "linux"))]
5 use super::super::conv
::syscall_ret_owned_fd
;
6 use super::super::conv
::{borrowed_fd, no_fd, ret}
;
7 use super::super::offset
::libc_mmap
;
8 #[cfg(not(target_os = "redox"))]
9 use super::types
::Advice
;
10 #[cfg(any(target_os = "emscripten", target_os = "linux"))]
11 use super::types
::MremapFlags
;
12 use super::types
::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags}
;
13 #[cfg(any(target_os = "android", target_os = "linux"))]
14 use super::types
::{MlockFlags, UserfaultfdFlags}
;
15 use crate::fd
::BorrowedFd
;
16 #[cfg(any(target_os = "android", target_os = "linux"))]
17 use crate::fd
::OwnedFd
;
20 #[cfg(not(target_os = "redox"))]
21 pub(crate) fn madvise(addr
: *mut c
::c_void
, len
: usize, advice
: Advice
) -> io
::Result
<()> {
22 // On Linux platforms, `MADV_DONTNEED` has the same value as
23 // `POSIX_MADV_DONTNEED` but different behavior. We remap it to a different
24 // value, and check for it here.
25 #[cfg(target_os = "linux")]
26 if let Advice
::LinuxDontNeed
= advice
{
27 return unsafe { ret(c::madvise(addr, len, c::MADV_DONTNEED)) }
;
30 #[cfg(not(target_os = "android"))]
32 let err
= unsafe { c::posix_madvise(addr, len, advice as c::c_int) }
;
34 // `posix_madvise` returns its error status rather than using `errno`.
42 #[cfg(target_os = "android")]
44 if let Advice
::DontNeed
= advice
{
45 // Do nothing. Linux's `MADV_DONTNEED` isn't the same as
46 // `POSIX_MADV_DONTNEED`, so just discard `MADV_DONTNEED`.
49 unsafe { ret(c::madvise(addr, len, advice as c::c_int)) }
54 pub(crate) unsafe fn msync(addr
: *mut c
::c_void
, len
: usize, flags
: MsyncFlags
) -> io
::Result
<()> {
55 let err
= c
::msync(addr
, len
, flags
.bits());
57 // `msync` returns its error status rather than using `errno`.
67 /// `mmap` is primarily unsafe due to the `addr` parameter, as anything working
68 /// with memory pointed to by raw pointers is unsafe.
69 pub(crate) unsafe fn mmap(
76 ) -> io
::Result
<*mut c
::c_void
> {
85 if res
== c
::MAP_FAILED
{
86 Err(io
::Errno
::last_os_error())
94 /// `mmap` is primarily unsafe due to the `addr` parameter, as anything working
95 /// with memory pointed to by raw pointers is unsafe.
96 pub(crate) unsafe fn mmap_anonymous(
101 ) -> io
::Result
<*mut c
::c_void
> {
106 flags
.bits() | c
::MAP_ANONYMOUS
,
110 if res
== c
::MAP_FAILED
{
111 Err(io
::Errno
::last_os_error())
117 pub(crate) unsafe fn mprotect(
120 flags
: MprotectFlags
,
121 ) -> io
::Result
<()> {
122 ret(c
::mprotect(ptr
, len
, flags
.bits()))
125 pub(crate) unsafe fn munmap(ptr
: *mut c
::c_void
, len
: usize) -> io
::Result
<()> {
126 ret(c
::munmap(ptr
, len
))
131 /// `mremap` is primarily unsafe due to the `old_address` parameter, as
132 /// anything working with memory pointed to by raw pointers is unsafe.
133 #[cfg(any(target_os = "emscripten", target_os = "linux"))]
134 pub(crate) unsafe fn mremap(
135 old_address
: *mut c
::c_void
,
139 ) -> io
::Result
<*mut c
::c_void
> {
140 let res
= c
::mremap(old_address
, old_size
, new_size
, flags
.bits());
141 if res
== c
::MAP_FAILED
{
142 Err(io
::Errno
::last_os_error())
150 /// `mremap_fixed` is primarily unsafe due to the `old_address` and
151 /// `new_address` parameters, as anything working with memory pointed to by raw
152 /// pointers is unsafe.
153 #[cfg(any(target_os = "emscripten", target_os = "linux"))]
154 pub(crate) unsafe fn mremap_fixed(
155 old_address
: *mut c
::c_void
,
159 new_address
: *mut c
::c_void
,
160 ) -> io
::Result
<*mut c
::c_void
> {
165 flags
.bits() | c
::MAP_FIXED
,
168 if res
== c
::MAP_FAILED
{
169 Err(io
::Errno
::last_os_error())
177 /// `mlock` operates on raw pointers and may round out to the nearest page
180 pub(crate) unsafe fn mlock(addr
: *mut c
::c_void
, length
: usize) -> io
::Result
<()> {
181 ret(c
::mlock(addr
, length
))
186 /// `mlock_with` operates on raw pointers and may round out to the nearest page
188 #[cfg(any(target_os = "android", target_os = "linux"))]
190 pub(crate) unsafe fn mlock_with(
191 addr
: *mut c
::c_void
,
194 ) -> io
::Result
<()> {
197 addr
: *const c
::c_void
,
200 ) via SYS_mlock2
-> c
::c_int
203 ret(mlock2(addr
, length
, flags
.bits()))
208 /// `munlock` operates on raw pointers and may round out to the nearest page
211 pub(crate) unsafe fn munlock(addr
: *mut c
::c_void
, length
: usize) -> io
::Result
<()> {
212 ret(c
::munlock(addr
, length
))
215 #[cfg(any(target_os = "android", target_os = "linux"))]
216 pub(crate) unsafe fn userfaultfd(flags
: UserfaultfdFlags
) -> io
::Result
<OwnedFd
> {
217 syscall_ret_owned_fd(c
::syscall(c
::SYS_userfaultfd
, flags
.bits()))