Skip to main content

relibc/header/sys_mman/
mod.rs

1//! `sys/mman.h` implementation.
2//!
3//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_mman.h.html>.
4
5use crate::{
6    c_str::{CStr, CString},
7    error::{Errno, ResultExt},
8    header::{fcntl, unistd},
9    platform::{
10        ERRNO, Pal, Sys,
11        types::{c_char, c_int, c_void, mode_t, off_t, size_t},
12    },
13};
14
15pub use self::sys::*;
16
17#[cfg(target_os = "linux")]
18#[path = "linux.rs"]
19pub mod sys;
20
21#[cfg(target_os = "redox")]
22#[path = "redox.rs"]
23pub mod sys;
24
25pub const MADV_NORMAL: c_int = 0;
26pub const MADV_RANDOM: c_int = 1;
27pub const MADV_SEQUENTIAL: c_int = 2;
28pub const MADV_WILLNEED: c_int = 3;
29pub const MADV_DONTNEED: c_int = 4;
30
31pub const MAP_SHARED: c_int = 0x0001;
32pub const MAP_PRIVATE: c_int = 0x0002;
33pub const MAP_TYPE: c_int = 0x000F;
34pub const MAP_ANON: c_int = 0x0020;
35pub const MAP_ANONYMOUS: c_int = MAP_ANON;
36pub const MAP_STACK: c_int = 0x20000;
37/// cbindgen:ignore
38pub const MAP_FAILED: *mut c_void = usize::wrapping_neg(1) as *mut c_void;
39
40pub const MREMAP_MAYMOVE: c_int = 1;
41
42pub const MS_ASYNC: c_int = 0x0001;
43pub const MS_INVALIDATE: c_int = 0x0002;
44pub const MS_SYNC: c_int = 0x0004;
45
46pub const MCL_CURRENT: c_int = 1;
47pub const MCL_FUTURE: c_int = 2;
48
49pub const POSIX_MADV_NORMAL: c_int = 0;
50pub const POSIX_MADV_RANDOM: c_int = 1;
51pub const POSIX_MADV_SEQUENTIAL: c_int = 2;
52pub const POSIX_MADV_WILLNEED: c_int = 3;
53pub const POSIX_MADV_WONTNEED: c_int = 4;
54
55/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man2/madvise.2.html>.
56#[unsafe(no_mangle)]
57pub unsafe extern "C" fn madvise(addr: *mut c_void, len: size_t, flags: c_int) -> c_int {
58    unsafe { Sys::madvise(addr, len, flags) }
59        .map(|()| 0)
60        .or_minus_one_errno()
61}
62
63/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlock.html>.
64#[unsafe(no_mangle)]
65pub unsafe extern "C" fn mlock(addr: *const c_void, len: size_t) -> c_int {
66    unsafe { Sys::mlock(addr, len) }
67        .map(|()| 0)
68        .or_minus_one_errno()
69}
70
71/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlockall.html>.
72#[unsafe(no_mangle)]
73pub unsafe extern "C" fn mlockall(flags: c_int) -> c_int {
74    unsafe { Sys::mlockall(flags) }
75        .map(|()| 0)
76        .or_minus_one_errno()
77}
78
79/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mmap.html>.
80#[unsafe(no_mangle)]
81pub unsafe extern "C" fn mmap(
82    addr: *mut c_void,
83    len: size_t,
84    prot: c_int,
85    flags: c_int,
86    fildes: c_int,
87    off: off_t,
88) -> *mut c_void {
89    match unsafe { Sys::mmap(addr, len, prot, flags, fildes, off) } {
90        Ok(ptr) => ptr,
91        Err(Errno(errno)) => {
92            ERRNO.set(errno);
93            MAP_FAILED
94        }
95    }
96}
97
98/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mprotect.html>.
99#[unsafe(no_mangle)]
100pub unsafe extern "C" fn mprotect(addr: *mut c_void, len: size_t, prot: c_int) -> c_int {
101    unsafe { Sys::mprotect(addr, len, prot) }
102        .map(|()| 0)
103        .or_minus_one_errno()
104}
105
106/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man2/mremap.2.html>.
107#[unsafe(no_mangle)]
108pub unsafe extern "C" fn mremap(
109    old_address: *mut c_void,
110    old_size: size_t,
111    new_size: size_t,
112    flags: c_int,
113    mut __valist: ...
114) -> *mut c_void {
115    let new_address = unsafe { __valist.next_arg::<*mut c_void>() };
116    match unsafe { Sys::mremap(old_address, old_size, new_size, flags, new_address) } {
117        Ok(ptr) => ptr,
118        Err(Errno(errno)) => {
119            ERRNO.set(errno);
120            MAP_FAILED
121        }
122    }
123}
124
125/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/msync.html>.
126#[unsafe(no_mangle)]
127pub unsafe extern "C" fn msync(addr: *mut c_void, len: size_t, flags: c_int) -> c_int {
128    unsafe { Sys::msync(addr, len, flags) }
129        .map(|()| 0)
130        .or_minus_one_errno()
131}
132
133/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlock.html>.
134#[unsafe(no_mangle)]
135pub unsafe extern "C" fn munlock(addr: *const c_void, len: size_t) -> c_int {
136    unsafe { Sys::munlock(addr, len) }
137        .map(|()| 0)
138        .or_minus_one_errno()
139}
140
141/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlockall.html>.
142#[unsafe(no_mangle)]
143pub unsafe extern "C" fn munlockall() -> c_int {
144    unsafe { Sys::munlockall() }
145        .map(|()| 0)
146        .or_minus_one_errno()
147}
148
149/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/munmap.html>.
150#[unsafe(no_mangle)]
151pub unsafe extern "C" fn munmap(addr: *mut c_void, len: size_t) -> c_int {
152    unsafe { Sys::munmap(addr, len) }
153        .map(|()| 0)
154        .or_minus_one_errno()
155}
156
157#[cfg(target_os = "linux")]
158static SHM_PATH: &[u8] = b"/dev/shm/";
159
160#[cfg(target_os = "redox")]
161static SHM_PATH: &[u8] = b"/scheme/shm/";
162
163unsafe fn shm_path(name: *const c_char) -> CString {
164    let name_c = unsafe { CStr::from_ptr(name) };
165
166    let mut path = SHM_PATH.to_vec();
167
168    let mut skip_slash = true;
169    for &b in name_c.to_bytes() {
170        if skip_slash {
171            if b == b'/' {
172                continue;
173            } else {
174                skip_slash = false;
175            }
176        }
177        path.push(b);
178    }
179
180    unsafe { CString::from_vec_unchecked(path) }
181}
182
183/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/shm_open.html>.
184#[unsafe(no_mangle)]
185pub unsafe extern "C" fn shm_open(name: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
186    let path = unsafe { shm_path(name) };
187    unsafe { fcntl::open(path.as_ptr(), oflag, mode) }
188}
189
190/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/shm_unlink.html>.
191#[unsafe(no_mangle)]
192pub unsafe extern "C" fn shm_unlink(name: *const c_char) -> c_int {
193    let path = unsafe { shm_path(name) };
194    unsafe { unistd::unlink(path.as_ptr()) }
195}