@@ -891,6 +891,10 @@ pub enum MapError {
891
891
/// If using `MapAddr`, the address + `min_len` was outside of the process's address space. If
892
892
/// using `MapFd`, the target of the fd didn't have enough resources to fulfill the request.
893
893
ErrNoMem ,
894
+ /// A zero-length map was requested. This is invalid according to
895
+ /// [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html). Not all
896
+ /// platforms obey this, but this wrapper does.
897
+ ErrZeroLength ,
894
898
/// Unrecognized error. The inner value is the unrecognized errno.
895
899
ErrUnknown ( int ) ,
896
900
/// ## The following are win32-specific
@@ -922,6 +926,7 @@ impl fmt::Default for MapError {
922
926
ErrUnsupProt => "Protection mode unsupported" ,
923
927
ErrUnsupOffset => "Offset in virtual memory mode is unsupported" ,
924
928
ErrAlreadyExists => "File mapping for specified file already exists" ,
929
+ ErrZeroLength => "Zero-length mapping not allowed" ,
925
930
ErrUnknown ( code) => { write ! ( out. buf, "Unknown error = {}" , code) ; return } ,
926
931
ErrVirtualAlloc ( code) => { write ! ( out. buf, "VirtualAlloc failure = {}" , code) ; return } ,
927
932
ErrCreateFileMappingW ( code) => {
@@ -939,10 +944,14 @@ impl fmt::Default for MapError {
939
944
940
945
#[ cfg( unix) ]
941
946
impl MemoryMap {
942
- /// Create a new mapping with the given `options`, at least `min_len` bytes long.
947
+ /// Create a new mapping with the given `options`, at least `min_len` bytes long. `min_len`
948
+ /// must be greater than zero; see the note on `ErrZeroLength`.
943
949
pub fn new ( min_len : uint , options : & [ MapOption ] ) -> Result < MemoryMap , MapError > {
944
950
use libc:: off_t;
945
951
952
+ if min_len == 0 {
953
+ return Err ( ErrZeroLength )
954
+ }
946
955
let mut addr: * u8 = ptr:: null ( ) ;
947
956
let mut prot = 0 ;
948
957
let mut flags = libc:: MAP_PRIVATE ;
@@ -1005,6 +1014,8 @@ impl MemoryMap {
1005
1014
impl Drop for MemoryMap {
1006
1015
/// Unmap the mapping. Fails the task if `munmap` fails.
1007
1016
fn drop ( & mut self ) {
1017
+ if self . len == 0 { /* workaround for dummy_stack */ return ; }
1018
+
1008
1019
unsafe {
1009
1020
match libc:: munmap ( self . data as * c_void , self . len as libc:: size_t ) {
1010
1021
0 => ( ) ,
@@ -1442,7 +1453,7 @@ mod tests {
1442
1453
os::MapWritable
1443
1454
]) {
1444
1455
Ok(chunk) => chunk,
1445
- Err(msg) => fail!(msg.to_str() )
1456
+ Err(msg) => fail!(" { } ", msg)
1446
1457
};
1447
1458
assert!(chunk.len >= 16);
1448
1459
0 commit comments