Update #2859. --- cpukit/posix/include/rtems/posix/mmanimpl.h | 4 ++- cpukit/posix/src/mmap.c | 43 +++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/cpukit/posix/include/rtems/posix/mmanimpl.h b/cpukit/posix/include/rtems/posix/mmanimpl.h index 9743685..78bda53 100644 --- a/cpukit/posix/include/rtems/posix/mmanimpl.h +++ b/cpukit/posix/include/rtems/posix/mmanimpl.h @@ -16,12 +16,14 @@ #ifndef _RTEMS_POSIX_MMANIMPL_H #define _RTEMS_POSIX_MMANIMPL_H -#include <rtems/chain.h> +#include <rtems/chain.h> /* FIXME: use score chains for proper layering? */ #ifdef __cplusplus extern "C" { #endif +/* FIXME: add Doxygen */ + /** * Every mmap'ed region has a mapping. */ diff --git a/cpukit/posix/src/mmap.c b/cpukit/posix/src/mmap.c index c05a65e..3c5f81e 100644 --- a/cpukit/posix/src/mmap.c +++ b/cpukit/posix/src/mmap.c @@ -1,5 +1,10 @@ +/** + * @file + */ + /* * Copyright (c) 2012 Chris Johns (chr...@rtems.org) + * Copyright (c) 2017 Gedare Bloom (ged...@rtems.org) * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -49,11 +54,14 @@ bool mmap_mappings_lock_create( * the libio lock is locked and we then test the mapping lock again. If not * present we create the mapping lock then release libio lock. */ + /* FIXME: double-checked locking anti-pattern. */ if ( mmap_mappings_lock == 0 ) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_chain_initialize_empty( &mmap_mappings ); rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); + /* FIXME: account for semaphore in confdefs, or maybe just use the + * rtems_libio_semaphore? */ if ( mmap_mappings_lock == 0 ) sc = rtems_semaphore_create( rtems_build_name( 'M', 'M', 'A', 'P' ), 1, @@ -140,20 +148,40 @@ void *mmap( * not normally have protections but we cannot hide access to memory. */ if ( prot == PROT_NONE ) { - errno = EINVAL; + errno = ENOTSUP; return MAP_FAILED; } /* - * Check to see if the mapping is valid for the file. + * We can not normally provide restriction of write access. Reject any + * attempt to map without write permission, since we are not able to + * prevent a write from succeeding. + */ + if ( PROT_WRITE != (prot & PROT_WRITE) ) { + errno = ENOTSUP; + return MAP_FAILED; + } + + /* + * Check to see if the mapping is valid for a regular file. */ if ( S_ISREG( sb.st_mode ) + /* FIXME: Should this be using strict inequality comparisons? It would + * be valid to map a region exactly equal to the st_size, e.g. see below. */ && (( off >= sb.st_size ) || (( off + len ) >= sb.st_size ))) { errno = EOVERFLOW; return MAP_FAILED; } /* + * Check to see if the mapping is valid for other file/object types. + */ + if ( sb.st_size < off + len ) { + errno = ENXIO; + return MAP_FAILED; + } + + /* * Obtain the mmap lock. Sets errno on failure. */ if ( !mmap_mappings_lock_obtain( ) ) @@ -200,7 +228,7 @@ void *mmap( } /* - * Do not seek on character devices, pipes or sockets. + * 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 ) { @@ -212,6 +240,7 @@ void *mmap( } } + /* read updates atime satisfying POSIX spec for mmap */ r = read( fildes, mapping->addr, len ); if ( r != len ) { @@ -222,6 +251,14 @@ void *mmap( return MAP_FAILED; } + /* 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? */ + + /* FIXME: add an extra reference to the file associated with fildes that + * is not removed by a subsequent close(). This reference shall be removed + * when there are no more mappings to the file. */ + rtems_chain_append( &mmap_mappings, &mapping->node ); mmap_mappings_lock_release( ); -- 2.7.4 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel