[PATCH 6/6] posix/mmap: update for MAP_FIXED
Gedare Bloom
gedare at rtems.org
Fri Mar 31 20:47:04 UTC 2017
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
More information about the devel
mailing list