1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
use {Errno, Error, Result, NixPath};
use fcntl::OFlag;
use libc::{self, c_void, size_t, off_t, mode_t};
use sys::stat::Mode;
use std::os::unix::io::RawFd;
pub use self::consts::*;
libc_bitflags!{
flags ProtFlags: libc::c_int {
PROT_NONE,
PROT_READ,
PROT_WRITE,
PROT_EXEC,
#[cfg(any(target_os = "linux", target_os = "android"))]
PROT_GROWSDOWN,
#[cfg(any(target_os = "linux", target_os = "android"))]
PROT_GROWSUP,
}
}
#[cfg(any(target_os = "linux", target_os = "android"))]
mod consts {
use libc::{self, c_int};
bitflags!{
flags MapFlags: c_int {
const MAP_FILE = libc::MAP_FILE,
const MAP_SHARED = libc::MAP_SHARED,
const MAP_PRIVATE = libc::MAP_PRIVATE,
const MAP_FIXED = libc::MAP_FIXED,
const MAP_ANON = libc::MAP_ANON,
const MAP_ANONYMOUS = libc::MAP_ANON,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
const MAP_32BIT = libc::MAP_32BIT,
const MAP_GROWSDOWN = libc::MAP_GROWSDOWN,
const MAP_DENYWRITE = libc::MAP_DENYWRITE,
const MAP_EXECUTABLE = libc::MAP_EXECUTABLE,
const MAP_LOCKED = libc::MAP_LOCKED,
const MAP_NORESERVE = libc::MAP_NORESERVE,
const MAP_POPULATE = libc::MAP_POPULATE,
const MAP_NONBLOCK = libc::MAP_NONBLOCK,
const MAP_STACK = libc::MAP_STACK,
const MAP_HUGETLB = libc::MAP_HUGETLB,
}
}
pub type MmapAdvise = c_int;
pub const MADV_NORMAL : MmapAdvise = 0;
pub const MADV_RANDOM : MmapAdvise = 1;
pub const MADV_SEQUENTIAL : MmapAdvise = 2;
pub const MADV_WILLNEED : MmapAdvise = 3;
pub const MADV_DONTNEED : MmapAdvise = 4;
pub const MADV_REMOVE : MmapAdvise = 9;
pub const MADV_DONTFORK : MmapAdvise = 10;
pub const MADV_DOFORK : MmapAdvise = 11;
pub const MADV_MERGEABLE : MmapAdvise = 12;
pub const MADV_UNMERGEABLE: MmapAdvise = 13;
pub const MADV_HUGEPAGE : MmapAdvise = 14;
pub const MADV_NOHUGEPAGE : MmapAdvise = 15;
pub const MADV_DONTDUMP : MmapAdvise = 16;
pub const MADV_DODUMP : MmapAdvise = 17;
pub const MADV_HWPOISON : MmapAdvise = 100;
bitflags!{
flags MsFlags: c_int {
const MS_ASYNC = libc::MS_ASYNC,
const MS_INVALIDATE = libc::MS_INVALIDATE,
const MS_SYNC = libc::MS_SYNC,
}
}
pub const MAP_FAILED: isize = -1;
}
#[cfg(any(target_os = "macos",
target_os = "ios"))]
mod consts {
use libc::{self, c_int};
bitflags!{
flags MapFlags: c_int {
const MAP_FILE = libc::MAP_FILE,
const MAP_SHARED = libc::MAP_SHARED,
const MAP_PRIVATE = libc::MAP_PRIVATE,
const MAP_FIXED = libc::MAP_FIXED,
const MAP_ANON = libc::MAP_ANON,
const MAP_NOCACHE = libc::MAP_NOCACHE,
const MAP_JIT = libc::MAP_JIT,
}
}
pub type MmapAdvise = c_int;
pub const MADV_NORMAL : MmapAdvise = 0;
pub const MADV_RANDOM : MmapAdvise = 1;
pub const MADV_SEQUENTIAL : MmapAdvise = 2;
pub const MADV_WILLNEED : MmapAdvise = 3;
pub const MADV_DONTNEED : MmapAdvise = 4;
pub const MADV_FREE : MmapAdvise = 5;
pub const MADV_ZERO_WIRED_PAGES: MmapAdvise = 6;
pub const MADV_FREE_REUSABLE : MmapAdvise = 7;
pub const MADV_FREE_REUSE : MmapAdvise = 8;
pub const MADV_CAN_REUSE : MmapAdvise = 9;
bitflags!{
flags MsFlags: c_int {
const MS_ASYNC = libc::MS_ASYNC,
const MS_INVALIDATE = libc::MS_INVALIDATE,
const MS_KILLPAGES = libc::MS_KILLPAGES,
const MS_DEACTIVATE = libc::MS_DEACTIVATE,
const MS_SYNC = libc::MS_SYNC,
}
}
pub const MAP_FAILED: isize = -1;
}
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd"))]
mod consts {
use libc::{self, c_int};
bitflags!{
flags MapFlags: c_int {
const MAP_FILE = libc::MAP_FILE,
const MAP_SHARED = libc::MAP_SHARED,
const MAP_PRIVATE = libc::MAP_PRIVATE,
const MAP_FIXED = libc::MAP_FIXED,
const MAP_RENAME = libc::MAP_RENAME,
const MAP_NORESERVE = libc::MAP_NORESERVE,
const MAP_HASSEMAPHORE = libc::MAP_HASSEMAPHORE,
#[cfg(not(any(target_os = "openbsd", target_os = "netbsd")))]
const MAP_STACK = libc::MAP_STACK,
#[cfg(target_os = "netbsd")]
const MAP_WIRED = libc::MAP_WIRED,
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
const MAP_NOSYNC = libc::MAP_NOSYNC,
const MAP_ANON = libc::MAP_ANON,
}
}
pub type MmapAdvise = c_int;
pub const MADV_NORMAL : MmapAdvise = 0;
pub const MADV_RANDOM : MmapAdvise = 1;
pub const MADV_SEQUENTIAL : MmapAdvise = 2;
pub const MADV_WILLNEED : MmapAdvise = 3;
pub const MADV_DONTNEED : MmapAdvise = 4;
pub const MADV_FREE : MmapAdvise = 5;
pub const MADV_NOSYNC : MmapAdvise = 6;
pub const MADV_AUTOSYNC : MmapAdvise = 7;
pub const MADV_NOCORE : MmapAdvise = 8;
pub const MADV_CORE : MmapAdvise = 9;
#[cfg(not(target_os = "dragonfly"))]
pub const MADV_PROTECT : MmapAdvise = 10;
#[cfg(target_os = "dragonfly")]
pub const MADV_INVAL : MmapAdvise = 10;
#[cfg(target_os = "dragonfly")]
pub const MADV_SETMAP : MmapAdvise = 11;
bitflags!{
flags MsFlags: c_int {
const MS_ASYNC = libc::MS_ASYNC,
const MS_INVALIDATE = libc::MS_INVALIDATE,
#[cfg(not(target_os = "dragonfly"))]
const MS_KILLPAGES = 0x0004,
#[cfg(not(target_os = "dragonfly"))]
const MS_DEACTIVATE = 0x0004,
const MS_SYNC = libc::MS_SYNC,
}
}
pub const MAP_FAILED: isize = -1;
}
mod ffi {
use libc::{c_void, size_t, c_int, c_char, mode_t};
pub use libc::{mmap, munmap};
#[allow(improper_ctypes)]
extern {
pub fn shm_open(name: *const c_char, oflag: c_int, mode: mode_t) -> c_int;
pub fn shm_unlink(name: *const c_char) -> c_int;
pub fn mlock(addr: *const c_void, len: size_t) -> c_int;
pub fn munlock(addr: *const c_void, len: size_t) -> c_int;
pub fn madvise (addr: *const c_void, len: size_t, advice: c_int) -> c_int;
pub fn msync (addr: *const c_void, len: size_t, flags: c_int) -> c_int;
}
}
pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
Errno::result(ffi::mlock(addr, length)).map(drop)
}
pub fn munlock(addr: *const c_void, length: size_t) -> Result<()> {
Errno::result(unsafe { ffi::munlock(addr, length) }).map(drop)
}
pub fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: MapFlags, fd: RawFd, offset: off_t) -> Result<*mut c_void> {
let ret = unsafe { ffi::mmap(addr, length, prot.bits(), flags.bits(), fd, offset) };
if ret as isize == MAP_FAILED {
Err(Error::Sys(Errno::last()))
} else {
Ok(ret)
}
}
pub fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
Errno::result(unsafe { ffi::munmap(addr, len) }).map(drop)
}
pub fn madvise(addr: *const c_void, length: size_t, advise: MmapAdvise) -> Result<()> {
Errno::result(unsafe { ffi::madvise(addr, length, advise) }).map(drop)
}
pub fn msync(addr: *const c_void, length: size_t, flags: MsFlags) -> Result<()> {
Errno::result(unsafe { ffi::msync(addr, length, flags.bits()) }).map(drop)
}
pub fn shm_open<P: ?Sized + NixPath>(name: &P, flag: OFlag, mode: Mode) -> Result<RawFd> {
let ret = try!(name.with_nix_path(|cstr| {
unsafe {
ffi::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as mode_t)
}
}));
Errno::result(ret)
}
pub fn shm_unlink<P: ?Sized + NixPath>(name: &P) -> Result<()> {
let ret = try!(name.with_nix_path(|cstr| {
unsafe { ffi::shm_unlink(cstr.as_ptr()) }
}));
Errno::result(ret).map(drop)
}