• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! linux_raw syscalls supporting `rustix::io`.
2 //!
3 //! # Safety
4 //!
5 //! See the `rustix::backend` module documentation for details.
6 #![allow(unsafe_code)]
7 #![allow(clippy::undocumented_unsafe_blocks)]
8 
9 use super::super::c;
10 #[cfg(target_pointer_width = "64")]
11 use super::super::conv::loff_t_from_u64;
12 use super::super::conv::{c_uint, no_fd, pass_usize, ret, ret_owned_fd, ret_void_star};
13 use super::types::{
14     Advice, MapFlags, MlockFlags, MprotectFlags, MremapFlags, MsyncFlags, ProtFlags,
15     UserfaultfdFlags,
16 };
17 use crate::fd::{BorrowedFd, OwnedFd};
18 use crate::io;
19 #[cfg(target_pointer_width = "32")]
20 use core::convert::TryInto;
21 use linux_raw_sys::general::MAP_ANONYMOUS;
22 
23 #[inline]
madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()>24 pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> {
25     unsafe {
26         ret(syscall!(
27             __NR_madvise,
28             addr,
29             pass_usize(len),
30             c_uint(advice as c::c_uint)
31         ))
32     }
33 }
34 
35 #[inline]
msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()>36 pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> {
37     ret(syscall!(__NR_msync, addr, pass_usize(len), flags))
38 }
39 
40 /// # Safety
41 ///
42 /// `mmap` is primarily unsafe due to the `addr` parameter, as anything working
43 /// with memory pointed to by raw pointers is unsafe.
44 #[inline]
mmap( addr: *mut c::c_void, length: usize, prot: ProtFlags, flags: MapFlags, fd: BorrowedFd<'_>, offset: u64, ) -> io::Result<*mut c::c_void>45 pub(crate) unsafe fn mmap(
46     addr: *mut c::c_void,
47     length: usize,
48     prot: ProtFlags,
49     flags: MapFlags,
50     fd: BorrowedFd<'_>,
51     offset: u64,
52 ) -> io::Result<*mut c::c_void> {
53     #[cfg(target_pointer_width = "32")]
54     {
55         ret_void_star(syscall!(
56             __NR_mmap2,
57             addr,
58             pass_usize(length),
59             prot,
60             flags,
61             fd,
62             (offset / 4096)
63                 .try_into()
64                 .map(pass_usize)
65                 .map_err(|_| io::Errno::INVAL)?
66         ))
67     }
68     #[cfg(target_pointer_width = "64")]
69     {
70         ret_void_star(syscall!(
71             __NR_mmap,
72             addr,
73             pass_usize(length),
74             prot,
75             flags,
76             fd,
77             loff_t_from_u64(offset)
78         ))
79     }
80 }
81 
82 /// # Safety
83 ///
84 /// `mmap` is primarily unsafe due to the `addr` parameter, as anything working
85 /// with memory pointed to by raw pointers is unsafe.
86 #[inline]
mmap_anonymous( addr: *mut c::c_void, length: usize, prot: ProtFlags, flags: MapFlags, ) -> io::Result<*mut c::c_void>87 pub(crate) unsafe fn mmap_anonymous(
88     addr: *mut c::c_void,
89     length: usize,
90     prot: ProtFlags,
91     flags: MapFlags,
92 ) -> io::Result<*mut c::c_void> {
93     #[cfg(target_pointer_width = "32")]
94     {
95         ret_void_star(syscall!(
96             __NR_mmap2,
97             addr,
98             pass_usize(length),
99             prot,
100             c_uint(flags.bits() | MAP_ANONYMOUS),
101             no_fd(),
102             pass_usize(0)
103         ))
104     }
105     #[cfg(target_pointer_width = "64")]
106     {
107         ret_void_star(syscall!(
108             __NR_mmap,
109             addr,
110             pass_usize(length),
111             prot,
112             c_uint(flags.bits() | MAP_ANONYMOUS),
113             no_fd(),
114             loff_t_from_u64(0)
115         ))
116     }
117 }
118 
119 #[inline]
mprotect( ptr: *mut c::c_void, len: usize, flags: MprotectFlags, ) -> io::Result<()>120 pub(crate) unsafe fn mprotect(
121     ptr: *mut c::c_void,
122     len: usize,
123     flags: MprotectFlags,
124 ) -> io::Result<()> {
125     ret(syscall!(__NR_mprotect, ptr, pass_usize(len), flags))
126 }
127 
128 /// # Safety
129 ///
130 /// `munmap` is primarily unsafe due to the `addr` parameter, as anything
131 /// working with memory pointed to by raw pointers is unsafe.
132 #[inline]
munmap(addr: *mut c::c_void, length: usize) -> io::Result<()>133 pub(crate) unsafe fn munmap(addr: *mut c::c_void, length: usize) -> io::Result<()> {
134     ret(syscall!(__NR_munmap, addr, pass_usize(length)))
135 }
136 
137 /// # Safety
138 ///
139 /// `mremap` is primarily unsafe due to the `old_address` parameter, as
140 /// anything working with memory pointed to by raw pointers is unsafe.
141 #[inline]
mremap( old_address: *mut c::c_void, old_size: usize, new_size: usize, flags: MremapFlags, ) -> io::Result<*mut c::c_void>142 pub(crate) unsafe fn mremap(
143     old_address: *mut c::c_void,
144     old_size: usize,
145     new_size: usize,
146     flags: MremapFlags,
147 ) -> io::Result<*mut c::c_void> {
148     ret_void_star(syscall!(
149         __NR_mremap,
150         old_address,
151         pass_usize(old_size),
152         pass_usize(new_size),
153         flags
154     ))
155 }
156 
157 /// # Safety
158 ///
159 /// `mremap_fixed` is primarily unsafe due to the `old_address` and
160 /// `new_address` parameters, as anything working with memory pointed to by raw
161 /// pointers is unsafe.
162 #[inline]
mremap_fixed( old_address: *mut c::c_void, old_size: usize, new_size: usize, flags: MremapFlags, new_address: *mut c::c_void, ) -> io::Result<*mut c::c_void>163 pub(crate) unsafe fn mremap_fixed(
164     old_address: *mut c::c_void,
165     old_size: usize,
166     new_size: usize,
167     flags: MremapFlags,
168     new_address: *mut c::c_void,
169 ) -> io::Result<*mut c::c_void> {
170     ret_void_star(syscall!(
171         __NR_mremap,
172         old_address,
173         pass_usize(old_size),
174         pass_usize(new_size),
175         flags,
176         new_address
177     ))
178 }
179 
180 /// # Safety
181 ///
182 /// `mlock` operates on raw pointers and may round out to the nearest page
183 /// boundaries.
184 #[inline]
mlock(addr: *mut c::c_void, length: usize) -> io::Result<()>185 pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> {
186     ret(syscall!(__NR_mlock, addr, pass_usize(length)))
187 }
188 
189 /// # Safety
190 ///
191 /// `mlock_with` operates on raw pointers and may round out to the nearest page
192 /// boundaries.
193 #[inline]
mlock_with( addr: *mut c::c_void, length: usize, flags: MlockFlags, ) -> io::Result<()>194 pub(crate) unsafe fn mlock_with(
195     addr: *mut c::c_void,
196     length: usize,
197     flags: MlockFlags,
198 ) -> io::Result<()> {
199     ret(syscall!(__NR_mlock2, addr, pass_usize(length), flags))
200 }
201 
202 /// # Safety
203 ///
204 /// `munlock` operates on raw pointers and may round out to the nearest page
205 /// boundaries.
206 #[inline]
munlock(addr: *mut c::c_void, length: usize) -> io::Result<()>207 pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> {
208     ret(syscall!(__NR_munlock, addr, pass_usize(length)))
209 }
210 
211 #[inline]
userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd>212 pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> {
213     ret_owned_fd(syscall_readonly!(__NR_userfaultfd, flags))
214 }
215