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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
use {Error, Result, NixPath};
use errno::Errno;
use fcntl::OFlag;
use libc::{c_void, size_t, off_t, mode_t};
use sys::stat::Mode;
use std::os::unix::io::RawFd;
pub use self::consts::*;
#[cfg(any(target_os = "linux", target_os = "android"))]
mod consts {
use libc::c_int;
pub type MmapFlag = c_int;
pub const MAP_SHARED: MmapFlag = 0x00001;
pub const MAP_PRIVATE: MmapFlag = 0x00002;
pub const MAP_FIXED: MmapFlag = 0x00010;
pub const MAP_FILE: MmapFlag = 0x00000;
pub const MAP_ANONYMOUS: MmapFlag = 0x00020;
pub const MAP_ANON: MmapFlag = MAP_ANONYMOUS;
pub const MAP_32BIT: MmapFlag = 0x00040;
pub const MAP_GROWSDOWN: MmapFlag = 0x00100;
pub const MAP_DENYWRITE: MmapFlag = 0x00800;
pub const MAP_EXECUTABLE: MmapFlag = 0x01000;
pub const MAP_LOCKED: MmapFlag = 0x02000;
pub const MAP_NORESERVE: MmapFlag = 0x04000;
pub const MAP_POPULATE: MmapFlag = 0x08000;
pub const MAP_NONBLOCK: MmapFlag = 0x10000;
pub const MAP_STACK: MmapFlag = 0x20000;
pub const MAP_HUGETLB: MmapFlag = 0x40000;
pub type MmapProt = c_int;
pub const PROT_READ: MmapProt = 0x1;
pub const PROT_WRITE: MmapProt = 0x2;
pub const PROT_EXEC: MmapProt = 0x4;
pub const PROT_NONE: MmapProt = 0x0;
pub const PROT_GROWSDOWN: MmapProt = 0x01000000;
pub const PROT_GROWSUP: MmapProt = 0x02000000;
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;
pub type MmapSync = c_int;
pub const MS_ASYNC : MmapSync = 1;
pub const MS_SYNC : MmapSync = 4;
pub const MS_INVALIDATE : MmapSync = 2;
pub const MAP_FAILED: isize = -1;
}
#[cfg(any(target_os = "macos",
target_os = "ios"))]
mod consts {
use libc::c_int;
pub type MmapFlag = c_int;
pub const MAP_SHARED: MmapFlag = 0x00001;
pub const MAP_PRIVATE: MmapFlag = 0x00002;
pub const MAP_FIXED: MmapFlag = 0x00010;
pub const MAP_NOCACHE: MmapFlag = 0x00400;
pub const MAP_JIT: MmapFlag = 0x00800;
pub type MmapProt = c_int;
pub const PROT_READ: MmapProt = 0x1;
pub const PROT_WRITE: MmapProt = 0x2;
pub const PROT_EXEC: MmapProt = 0x4;
pub const PROT_NONE: MmapProt = 0x0;
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;
pub type MmapSync = c_int;
pub const MS_ASYNC : MmapSync = 0x0001;
pub const MS_INVALIDATE : MmapSync = 0x0002;
pub const MS_SYNC : MmapSync = 0x0010;
pub const MS_KILLPAGES : MmapSync = 0x0004;
pub const MS_DEACTIVATE : MmapSync = 0x0008;
pub const MAP_FAILED: isize = -1;
}
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
mod consts {
use libc::c_int;
pub type MmapFlag = c_int;
pub const MAP_SHARED: MmapFlag = 0x00001;
pub const MAP_PRIVATE: MmapFlag = 0x00002;
pub const MAP_FIXED: MmapFlag = 0x00010;
pub const MAP_RENAME: MmapFlag = 0x00020;
pub const MAP_NORESERVE: MmapFlag = 0x00040;
pub const MAP_HASSEMAPHORE: MmapFlag = 0x00200;
pub const MAP_STACK: MmapFlag = 0x00400;
pub const MAP_NOSYNC: MmapFlag = 0x00800;
pub const MAP_FILE: MmapFlag = 0x00000;
pub const MAP_ANON: MmapFlag = 0x01000;
pub type MmapProt = c_int;
pub const PROT_READ: MmapProt = 0x1;
pub const PROT_WRITE: MmapProt = 0x2;
pub const PROT_EXEC: MmapProt = 0x4;
pub const PROT_NONE: MmapProt = 0x0;
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;
pub type MmapSync = c_int;
pub const MS_ASYNC : MmapSync = 0x0001;
pub const MS_INVALIDATE : MmapSync = 0x0002;
#[cfg(not(target_os = "dragonfly"))]
pub const MS_SYNC : MmapSync = 0x0010;
#[cfg(target_os = "dragonfly")]
pub const MS_SYNC : MmapSync = 0x0000;
#[cfg(not(target_os = "dragonfly"))]
pub const MS_KILLPAGES : MmapSync = 0x0004;
#[cfg(not(target_os = "dragonfly"))]
pub const MS_DEACTIVATE : MmapSync = 0x0008;
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};
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<()> {
match ffi::mlock(addr, length) {
0 => Ok(()),
_ => Err(Error::Sys(Errno::last()))
}
}
pub fn munlock(addr: *const c_void, length: size_t) -> Result<()> {
match unsafe { ffi::munlock(addr, length) } {
0 => Ok(()),
_ => Err(Error::Sys(Errno::last()))
}
}
pub fn mmap(addr: *mut c_void, length: size_t, prot: MmapProt, flags: MmapFlag, fd: RawFd, offset: off_t) -> Result<*mut c_void> {
let ret = unsafe { ffi::mmap(addr, length, prot, flags, 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<()> {
match unsafe { ffi::munmap(addr, len) } {
0 => Ok(()),
_ => Err(Error::Sys(Errno::last()))
}
}
pub fn madvise(addr: *const c_void, length: size_t, advise: MmapAdvise) -> Result<()> {
match unsafe { ffi::madvise(addr, length, advise) } {
0 => Ok(()),
_ => Err(Error::Sys(Errno::last()))
}
}
pub fn msync(addr: *const c_void, length: size_t, flags: MmapSync) -> Result<()> {
match unsafe { ffi::msync(addr, length, flags) } {
0 => Ok(()),
_ => Err(Error::Sys(Errno::last()))
}
}
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)
}
}));
if ret < 0 {
Err(Error::Sys(Errno::last()))
} else {
Ok(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()) }
}));
if ret < 0 {
Err(Error::Sys(Errno::last()))
} else {
Ok(())
}
}