@@ -116,6 +116,118 @@ fn test_mmap() {
116
116
assert_eq ! ( Error :: last_os_error( ) . raw_os_error( ) . unwrap( ) , libc:: EINVAL ) ;
117
117
}
118
118
119
+ #[ cfg( target_os = "linux" ) ]
120
+ fn test_mmap64 ( ) {
121
+ let page_size = page_size:: get ( ) ;
122
+ let ptr = unsafe {
123
+ libc:: mmap64 (
124
+ ptr:: null_mut ( ) ,
125
+ page_size,
126
+ libc:: PROT_READ | libc:: PROT_WRITE ,
127
+ libc:: MAP_PRIVATE | libc:: MAP_ANONYMOUS ,
128
+ -1 ,
129
+ 0 ,
130
+ )
131
+ } ;
132
+ assert ! ( !ptr. is_null( ) ) ;
133
+
134
+ // Ensure that freshly mapped allocations are zeroed
135
+ let slice = unsafe { slice:: from_raw_parts_mut ( ptr as * mut u8 , page_size) } ;
136
+ assert ! ( slice. iter( ) . all( |b| * b == 0 ) ) ;
137
+
138
+ // Do some writes, make sure they worked
139
+ for b in slice. iter_mut ( ) {
140
+ * b = 1 ;
141
+ }
142
+ assert ! ( slice. iter( ) . all( |b| * b == 1 ) ) ;
143
+
144
+ // Ensure that we can munmap
145
+ let res = unsafe { libc:: munmap ( ptr, page_size) } ;
146
+ assert_eq ! ( res, 0i32 ) ;
147
+
148
+ // Test all of our error conditions
149
+ let ptr = unsafe {
150
+ libc:: mmap64 (
151
+ ptr:: null_mut ( ) ,
152
+ page_size,
153
+ libc:: PROT_READ | libc:: PROT_WRITE ,
154
+ libc:: MAP_PRIVATE | libc:: MAP_SHARED , // Can't be both private and shared
155
+ -1 ,
156
+ 0 ,
157
+ )
158
+ } ;
159
+ assert_eq ! ( ptr, libc:: MAP_FAILED ) ;
160
+ assert_eq ! ( Error :: last_os_error( ) . raw_os_error( ) . unwrap( ) , libc:: EINVAL ) ;
161
+
162
+ let ptr = unsafe {
163
+ libc:: mmap64 (
164
+ ptr:: null_mut ( ) ,
165
+ 0 , // Can't map no memory
166
+ libc:: PROT_READ | libc:: PROT_WRITE ,
167
+ libc:: MAP_PRIVATE | libc:: MAP_ANONYMOUS ,
168
+ -1 ,
169
+ 0 ,
170
+ )
171
+ } ;
172
+ assert_eq ! ( ptr, libc:: MAP_FAILED ) ;
173
+ assert_eq ! ( Error :: last_os_error( ) . raw_os_error( ) . unwrap( ) , libc:: EINVAL ) ;
174
+
175
+ let ptr = unsafe {
176
+ libc:: mmap64 (
177
+ ptr:: invalid_mut ( page_size * 64 ) ,
178
+ page_size,
179
+ libc:: PROT_READ | libc:: PROT_WRITE ,
180
+ // We don't support MAP_FIXED
181
+ libc:: MAP_PRIVATE | libc:: MAP_ANONYMOUS | libc:: MAP_FIXED ,
182
+ -1 ,
183
+ 0 ,
184
+ )
185
+ } ;
186
+ assert_eq ! ( ptr, libc:: MAP_FAILED ) ;
187
+ assert_eq ! ( Error :: last_os_error( ) . raw_os_error( ) . unwrap( ) , libc:: ENOTSUP ) ;
188
+
189
+ // We don't support protections other than read+write
190
+ for prot in [ libc:: PROT_NONE , libc:: PROT_EXEC , libc:: PROT_READ , libc:: PROT_WRITE ] {
191
+ let ptr = unsafe {
192
+ libc:: mmap64 (
193
+ ptr:: null_mut ( ) ,
194
+ page_size,
195
+ prot,
196
+ libc:: MAP_PRIVATE | libc:: MAP_ANONYMOUS ,
197
+ -1 ,
198
+ 0 ,
199
+ )
200
+ } ;
201
+ assert_eq ! ( ptr, libc:: MAP_FAILED ) ;
202
+ assert_eq ! ( Error :: last_os_error( ) . raw_os_error( ) . unwrap( ) , libc:: ENOTSUP ) ;
203
+ }
204
+
205
+ // We report an error for mappings whose length cannot be rounded up to a multiple of
206
+ // the page size.
207
+ let ptr = unsafe {
208
+ libc:: mmap64 (
209
+ ptr:: null_mut ( ) ,
210
+ usize:: MAX - 1 ,
211
+ libc:: PROT_READ | libc:: PROT_WRITE ,
212
+ libc:: MAP_PRIVATE | libc:: MAP_ANONYMOUS ,
213
+ -1 ,
214
+ 0 ,
215
+ )
216
+ } ;
217
+ assert_eq ! ( ptr, libc:: MAP_FAILED ) ;
218
+
219
+ // We report an error when trying to munmap an address which is not a multiple of the page size
220
+ let res = unsafe { libc:: munmap ( ptr:: invalid_mut ( 1 ) , page_size) } ;
221
+ assert_eq ! ( res, -1 ) ;
222
+ assert_eq ! ( Error :: last_os_error( ) . raw_os_error( ) . unwrap( ) , libc:: EINVAL ) ;
223
+
224
+ // We report an error when trying to munmap a length that cannot be rounded up to a multiple of
225
+ // the page size.
226
+ let res = unsafe { libc:: munmap ( ptr:: invalid_mut ( page_size) , usize:: MAX - 1 ) } ;
227
+ assert_eq ! ( res, -1 ) ;
228
+ assert_eq ! ( Error :: last_os_error( ) . raw_os_error( ) . unwrap( ) , libc:: EINVAL ) ;
229
+ }
230
+
119
231
#[ cfg( target_os = "linux" ) ]
120
232
fn test_mremap ( ) {
121
233
let page_size = page_size:: get ( ) ;
@@ -165,5 +277,7 @@ fn test_mremap() {
165
277
fn main ( ) {
166
278
test_mmap ( ) ;
167
279
#[ cfg( target_os = "linux" ) ]
280
+ test_mmap64 ( ) ;
281
+ #[ cfg( target_os = "linux" ) ]
168
282
test_mremap ( ) ;
169
283
}
0 commit comments