Updates #2859. --- cpukit/posix/src/mmap.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-)
diff --git a/cpukit/posix/src/mmap.c b/cpukit/posix/src/mmap.c index b1d1653..9c70328 100644 --- a/cpukit/posix/src/mmap.c +++ b/cpukit/posix/src/mmap.c @@ -124,6 +124,7 @@ void *mmap( mmap_mapping *mapping; ssize_t r; rtems_libio_t *iop; + bool map_fixed; /* * Clear errno. @@ -202,13 +203,15 @@ void *mmap( if ( !mmap_mappings_lock_obtain( ) ) return MAP_FAILED; - if (( flags & MAP_FIXED ) == MAP_FIXED ) { + map_fixed = (flags & MAP_FIXED) == MAP_FIXED; + if ( map_fixed ) { rtems_chain_node* node = rtems_chain_first (&mmap_mappings); while ( !rtems_chain_is_tail( &mmap_mappings, node )) { /* * If the map is fixed see if this address is already mapped. At this * point in time if there is an overlap in the mappings we return an - * error. + * error. POSIX allows us to also return successfully by unmapping + * the overlapping prior mappings. */ mapping = (mmap_mapping*) node; if ( ( addr >= mapping->addr ) && @@ -234,7 +237,7 @@ void *mmap( mapping->flags = flags; mapping->iop = iop; - if (( flags & MAP_FIXED ) != MAP_FIXED ) { + if ( !map_fixed ) { mapping->addr = malloc( len ); if ( !mapping->addr ) { mmap_mappings_lock_release( ); @@ -242,26 +245,34 @@ void *mmap( errno = ENOMEM; return MAP_FAILED; } + } else { + mapping->addr = addr; + } - /* - * Do not seek on character devices, pipes, sockets, or memory objects. - */ - if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ) { - if ( lseek( fildes, off, SEEK_SET ) < 0 ) { - mmap_mappings_lock_release( ); + /* + * Do not seek on character devices, pipes, sockets, or memory objects. + */ + if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ) { + if ( lseek( fildes, off, SEEK_SET ) < 0 ) { + mmap_mappings_lock_release( ); + if ( !map_fixed ) { free( mapping->addr ); - free( mapping ); - return MAP_FAILED; } + free( mapping ); + return MAP_FAILED; } } + /* FIXME: MAP_SHARED is not supported. It's unclear how it could be. */ + /* read updates atime satisfying POSIX spec for mmap */ r = read( fildes, mapping->addr, len ); if ( r != len ) { mmap_mappings_lock_release( ); - free( mapping->addr ); + if ( !map_fixed ) { + free( mapping->addr ); + } free( mapping ); errno = ENXIO; return MAP_FAILED; @@ -280,14 +291,9 @@ void *mmap( shm_mmap(iop); } - /* FIXME: - * MAP_SHARED is not supported for regular files, and probably should be? - * MAP_PRIVATE is not supported for shared memory objects, and should be? - */ - /* FIXME: for a mapping with MAP_SHARED and PROT_WRITE the mtime/ctime * should be updated when there is a write reference to the mapped region. - * How do we make this happen? */ + * How do we make this happen? Anyway MAP_SHARED is not supported yet. */ /* add an extra reference to the file associated with fildes that * is not removed by a subsequent close(). This reference shall be removed -- 2.7.4 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel