@@ -116,6 +116,118 @@ fn test_mmap() {
116116 assert_eq ! ( Error :: last_os_error( ) . raw_os_error( ) . unwrap( ) , libc:: EINVAL ) ;
117117}
118118
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+
119231#[ cfg( target_os = "linux" ) ]
120232fn test_mremap ( ) {
121233 let page_size = page_size:: get ( ) ;
@@ -165,5 +277,7 @@ fn test_mremap() {
165277fn main ( ) {
166278 test_mmap ( ) ;
167279 #[ cfg( target_os = "linux" ) ]
280+ test_mmap64 ( ) ;
281+ #[ cfg( target_os = "linux" ) ]
168282 test_mremap ( ) ;
169283}
0 commit comments