[PATCH v5 1/2] posix/mmap: Add support for file handler and MAP_ANON

Kevin Kirspel kevin-kirspel at idexx.com
Thu Jun 29 14:36:43 UTC 2017


Added a mmap file handler to struct _rtems_filesystem_file_handlers_r.
Updated each file handler object to support the default mmap handler.
Updated mmap() to call the mmap handler for MAP_SHARED.
Added a mmap file handler for shm

Added support for MAP_ANON in mmap().

Updates #2859
---
 cpukit/dev/i2c/i2c-bus.c                        |   1 +
 cpukit/dev/i2c/i2c-dev.c                        |   1 +
 cpukit/dev/spi/spi-bus.c                        |   1 +
 cpukit/libblock/src/blkdev-imfs.c               |   1 +
 cpukit/libcsupport/include/rtems/libio.h        |  38 ++++
 cpukit/libcsupport/include/rtems/termiostypes.h |  13 ++
 cpukit/libcsupport/src/__usrenv.c               |   1 +
 cpukit/libcsupport/src/termios.c                |   1 +
 cpukit/libfs/Makefile.am                        |   1 +
 cpukit/libfs/src/defaults/default_handlers.c    |   1 +
 cpukit/libfs/src/defaults/default_mmap.c        |  40 ++++
 cpukit/libfs/src/devfs/devfs_init.c             |   1 +
 cpukit/libfs/src/dosfs/msdos_handlers_dir.c     |   1 +
 cpukit/libfs/src/dosfs/msdos_handlers_file.c    |   1 +
 cpukit/libfs/src/imfs/imfs_dir_default.c        |   1 +
 cpukit/libfs/src/imfs/imfs_dir_minimal.c        |   1 +
 cpukit/libfs/src/imfs/imfs_fifo.c               |   1 +
 cpukit/libfs/src/imfs/imfs_handlers_device.c    |   1 +
 cpukit/libfs/src/imfs/imfs_linfile.c            |   1 +
 cpukit/libfs/src/imfs/imfs_link.c               |   1 +
 cpukit/libfs/src/imfs/imfs_memfile.c            |   1 +
 cpukit/libfs/src/imfs/imfs_symlink.c            |   1 +
 cpukit/libfs/src/jffs2/src/fs-rtems.c           |   3 +
 cpukit/libfs/src/nfsclient/src/nfs.c            |   3 +
 cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c      |   1 +
 cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c      |   1 +
 cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c     |   1 +
 cpukit/libfs/src/rfs/rtems-rfs-rtems.c          |   1 +
 cpukit/libnetworking/lib/ftpfs.c                |   2 +
 cpukit/libnetworking/lib/tftpDriver.c           |   1 +
 cpukit/libnetworking/rtems/rtems_syscall.c      |   1 +
 cpukit/posix/src/mmap.c                         | 257 ++++++++++++++----------
 cpukit/posix/src/munmap.c                       |  14 +-
 cpukit/posix/src/shmopen.c                      |  30 +++
 34 files changed, 312 insertions(+), 113 deletions(-)
 create mode 100644 cpukit/libfs/src/defaults/default_mmap.c

diff --git a/cpukit/dev/i2c/i2c-bus.c b/cpukit/dev/i2c/i2c-bus.c
index 0f27d06..1297b1e 100644
--- a/cpukit/dev/i2c/i2c-bus.c
+++ b/cpukit/dev/i2c/i2c-bus.c
@@ -218,6 +218,7 @@ static const rtems_filesystem_file_handlers_r i2c_bus_handler = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/dev/i2c/i2c-dev.c b/cpukit/dev/i2c/i2c-dev.c
index b00a9bd..680732f 100644
--- a/cpukit/dev/i2c/i2c-dev.c
+++ b/cpukit/dev/i2c/i2c-dev.c
@@ -115,6 +115,7 @@ static const rtems_filesystem_file_handlers_r i2c_dev_handler = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/dev/spi/spi-bus.c b/cpukit/dev/spi/spi-bus.c
index dd84b02..343e203 100644
--- a/cpukit/dev/spi/spi-bus.c
+++ b/cpukit/dev/spi/spi-bus.c
@@ -235,6 +235,7 @@ static const rtems_filesystem_file_handlers_r spi_bus_handler = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libblock/src/blkdev-imfs.c b/cpukit/libblock/src/blkdev-imfs.c
index 7a2d00b..f2008aa 100644
--- a/cpukit/libblock/src/blkdev-imfs.c
+++ b/cpukit/libblock/src/blkdev-imfs.c
@@ -222,6 +222,7 @@ static const rtems_filesystem_file_handlers_r rtems_blkdev_imfs_node = {
   .fdatasync_h = rtems_blkdev_imfs_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h
index 4669cb5..8226d18 100644
--- a/cpukit/libcsupport/include/rtems/libio.h
+++ b/cpukit/libcsupport/include/rtems/libio.h
@@ -977,6 +977,28 @@ typedef int (*rtems_filesystem_kqfilter_t)(
 );
 
 /**
+ * @brief MMAP support.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in, out] addr The starting address of the mapped memory.
+ * @param[in] len The maximum number of bytes to map.
+ * @param[in] prot The desired memory protection.
+ * @param[in] off The offset within the file descriptor to map.
+ *
+ * @retval 0 Successful operation.
+ * @retval error An error occurred.  This is usually EINVAL.
+ *
+ * @see rtems_filesystem_default_mmap().
+ */
+typedef int (*rtems_filesystem_mmap_t)(
+  rtems_libio_t *iop,
+  void **addr,
+  size_t len,
+  int prot,
+  off_t off
+);
+
+/**
  * @brief File system node operations table.
  */
 struct _rtems_filesystem_file_handlers_r {
@@ -995,6 +1017,7 @@ struct _rtems_filesystem_file_handlers_r {
   rtems_filesystem_kqfilter_t kqfilter_h;
   rtems_filesystem_readv_t readv_h;
   rtems_filesystem_writev_t writev_h;
+  rtems_filesystem_mmap_t mmap_h;
 };
 
 /**
@@ -1216,6 +1239,21 @@ int rtems_filesystem_default_kqfilter(
   struct knote *kn
 );
 
+/**
+ * @brief Default MMAP handler.
+ *
+ * @retval ENOTSUP Always.
+ *
+ * @see rtems_filesystem_mmap_t.
+ */
+int rtems_filesystem_default_mmap(
+  rtems_libio_t *iop,
+  void **addr,
+  size_t len,
+  int prot,
+  off_t off
+);
+
 /** @} */
 
 /**
diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h
index e91faa7..b3cac66 100644
--- a/cpukit/libcsupport/include/rtems/termiostypes.h
+++ b/cpukit/libcsupport/include/rtems/termiostypes.h
@@ -565,6 +565,19 @@ int rtems_termios_kqfilter(
 );
 
 /**
+ * @brief Termios mmap() filter filesystem node handler
+ *
+ * Real implementation is provided by libbsd.
+ */
+int rtems_termios_mmap(
+  rtems_libio_t *iop,
+  void         **addr,
+  size_t         len,
+  int            prot,
+  off_t          off
+);
+
+/**
  * @brief Termios poll() filesystem node handler.
  *
  * Real implementation is provided by libbsd.
diff --git a/cpukit/libcsupport/src/__usrenv.c b/cpukit/libcsupport/src/__usrenv.c
index a05295d..611e0d7 100644
--- a/cpukit/libcsupport/src/__usrenv.c
+++ b/cpukit/libcsupport/src/__usrenv.c
@@ -56,6 +56,7 @@ const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index a22ae95..7d84349 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -2212,6 +2212,7 @@ static const rtems_filesystem_file_handlers_r rtems_termios_imfs_handler = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_termios_kqfilter,
+  .mmap_h = rtems_termios_mmap,
   .poll_h = rtems_termios_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am
index 2a09aaa..0985b2f 100644
--- a/cpukit/libfs/Makefile.am
+++ b/cpukit/libfs/Makefile.am
@@ -33,6 +33,7 @@ libdefaultfs_a_SOURCES = \
     src/defaults/default_ftruncate_directory.c \
     src/defaults/default_handlers.c src/defaults/default_ops.c
 libdefaultfs_a_SOURCES += src/defaults/default_kqfilter.c
+libdefaultfs_a_SOURCES += src/defaults/default_mmap.c
 libdefaultfs_a_SOURCES += src/defaults/default_poll.c
 libdefaultfs_a_SOURCES += src/defaults/default_readv.c
 libdefaultfs_a_SOURCES += src/defaults/default_writev.c
diff --git a/cpukit/libfs/src/defaults/default_handlers.c b/cpukit/libfs/src/defaults/default_handlers.c
index 903cddc..3730f6c 100644
--- a/cpukit/libfs/src/defaults/default_handlers.c
+++ b/cpukit/libfs/src/defaults/default_handlers.c
@@ -34,6 +34,7 @@ const rtems_filesystem_file_handlers_r rtems_filesystem_handlers_default = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/defaults/default_mmap.c b/cpukit/libfs/src/defaults/default_mmap.c
new file mode 100644
index 0000000..08534ee
--- /dev/null
+++ b/cpukit/libfs/src/defaults/default_mmap.c
@@ -0,0 +1,40 @@
+/**
+ * @file
+ *
+ * @brief Default MMAP Handler
+ *
+ * @ingroup LibIOFSHandler
+ */
+
+/*
+ * Copyright (c) 2017 Kevin Kirspel (kirspkt at gmail.com)
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+
+int rtems_filesystem_default_mmap(
+  rtems_libio_t  *iop,
+  void          **addr,
+  size_t          len,
+  int             prot,
+  off_t           off
+)
+{
+  rtems_set_errno_and_return_minus_one( ENOTSUP );
+}
+
+int rtems_termios_mmap(
+  rtems_libio_t  *iop,
+  void          **addr,
+  size_t          len,
+  int             prot,
+  off_t           off
+) RTEMS_WEAK_ALIAS( rtems_filesystem_default_mmap );
diff --git a/cpukit/libfs/src/devfs/devfs_init.c b/cpukit/libfs/src/devfs/devfs_init.c
index cb5099c..1e960d2 100644
--- a/cpukit/libfs/src/devfs/devfs_init.c
+++ b/cpukit/libfs/src/devfs/devfs_init.c
@@ -52,6 +52,7 @@ const rtems_filesystem_file_handlers_r devFS_file_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
index 1365ca1..bc2d896 100644
--- a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
+++ b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
@@ -34,6 +34,7 @@ const rtems_filesystem_file_handlers_r msdos_dir_handlers = {
   .fdatasync_h = msdos_sync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_file.c b/cpukit/libfs/src/dosfs/msdos_handlers_file.c
index 0bea6e1..ed72fb6 100644
--- a/cpukit/libfs/src/dosfs/msdos_handlers_file.c
+++ b/cpukit/libfs/src/dosfs/msdos_handlers_file.c
@@ -34,6 +34,7 @@ const rtems_filesystem_file_handlers_r msdos_file_handlers = {
   .fdatasync_h = msdos_sync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/imfs/imfs_dir_default.c b/cpukit/libfs/src/imfs/imfs_dir_default.c
index b31a50e..a1fc243 100644
--- a/cpukit/libfs/src/imfs/imfs_dir_default.c
+++ b/cpukit/libfs/src/imfs/imfs_dir_default.c
@@ -130,6 +130,7 @@ static const rtems_filesystem_file_handlers_r IMFS_dir_default_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/imfs/imfs_dir_minimal.c b/cpukit/libfs/src/imfs/imfs_dir_minimal.c
index 3ef5173..e97468d 100644
--- a/cpukit/libfs/src/imfs/imfs_dir_minimal.c
+++ b/cpukit/libfs/src/imfs/imfs_dir_minimal.c
@@ -32,6 +32,7 @@ static const rtems_filesystem_file_handlers_r IMFS_dir_minimal_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/imfs/imfs_fifo.c b/cpukit/libfs/src/imfs/imfs_fifo.c
index d6c2187..b97694e 100644
--- a/cpukit/libfs/src/imfs/imfs_fifo.c
+++ b/cpukit/libfs/src/imfs/imfs_fifo.c
@@ -127,6 +127,7 @@ static const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c
index 0a7cb5f..df9f6fc 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_device.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c
@@ -45,6 +45,7 @@ static const rtems_filesystem_file_handlers_r IMFS_device_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/imfs/imfs_linfile.c b/cpukit/libfs/src/imfs/imfs_linfile.c
index 5840c16..57e106d 100644
--- a/cpukit/libfs/src/imfs/imfs_linfile.c
+++ b/cpukit/libfs/src/imfs/imfs_linfile.c
@@ -87,6 +87,7 @@ static const rtems_filesystem_file_handlers_r IMFS_linfile_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/imfs/imfs_link.c b/cpukit/libfs/src/imfs/imfs_link.c
index 06794af..add93e4 100644
--- a/cpukit/libfs/src/imfs/imfs_link.c
+++ b/cpukit/libfs/src/imfs/imfs_link.c
@@ -93,6 +93,7 @@ static const rtems_filesystem_file_handlers_r IMFS_link_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/imfs/imfs_memfile.c b/cpukit/libfs/src/imfs/imfs_memfile.c
index 2b6a496..2227bba 100644
--- a/cpukit/libfs/src/imfs/imfs_memfile.c
+++ b/cpukit/libfs/src/imfs/imfs_memfile.c
@@ -844,6 +844,7 @@ static const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/imfs/imfs_symlink.c b/cpukit/libfs/src/imfs/imfs_symlink.c
index 0f06446..4358ad6 100644
--- a/cpukit/libfs/src/imfs/imfs_symlink.c
+++ b/cpukit/libfs/src/imfs/imfs_symlink.c
@@ -95,6 +95,7 @@ static const rtems_filesystem_file_handlers_r IMFS_link_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/jffs2/src/fs-rtems.c b/cpukit/libfs/src/jffs2/src/fs-rtems.c
index 8084776..5e702ce 100644
--- a/cpukit/libfs/src/jffs2/src/fs-rtems.c
+++ b/cpukit/libfs/src/jffs2/src/fs-rtems.c
@@ -606,6 +606,7 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_directory_handlers = {
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fcntl_h = rtems_filesystem_default_fcntl,
 	.kqfilter_h = rtems_filesystem_default_kqfilter,
+	.mmap_h = rtems_filesystem_default_mmap,
 	.poll_h = rtems_filesystem_default_poll,
 	.readv_h = rtems_filesystem_default_readv,
 	.writev_h = rtems_filesystem_default_writev
@@ -748,6 +749,7 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_file_handlers = {
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fcntl_h = rtems_filesystem_default_fcntl,
 	.kqfilter_h = rtems_filesystem_default_kqfilter,
+	.mmap_h = rtems_filesystem_default_mmap,
 	.poll_h = rtems_filesystem_default_poll,
 	.readv_h = rtems_filesystem_default_readv,
 	.writev_h = rtems_filesystem_default_writev
@@ -766,6 +768,7 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_link_handlers = {
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fcntl_h = rtems_filesystem_default_fcntl,
 	.kqfilter_h = rtems_filesystem_default_kqfilter,
+	.mmap_h = rtems_filesystem_default_mmap,
 	.poll_h = rtems_filesystem_default_poll,
 	.readv_h = rtems_filesystem_default_readv,
 	.writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c
index 5673a24..87fef54 100644
--- a/cpukit/libfs/src/nfsclient/src/nfs.c
+++ b/cpukit/libfs/src/nfsclient/src/nfs.c
@@ -2884,6 +2884,7 @@ struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers = {
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fcntl_h     = rtems_filesystem_default_fcntl,
 	.kqfilter_h  = rtems_filesystem_default_kqfilter,
+	.mmap_h      = rtems_filesystem_default_mmap,
 	.poll_h      = rtems_filesystem_default_poll,
 	.readv_h     = rtems_filesystem_default_readv,
 	.writev_h    = rtems_filesystem_default_writev
@@ -2904,6 +2905,7 @@ struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers = {
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fcntl_h     = rtems_filesystem_default_fcntl,
 	.kqfilter_h  = rtems_filesystem_default_kqfilter,
+	.mmap_h      = rtems_filesystem_default_mmap,
 	.poll_h      = rtems_filesystem_default_poll,
 	.readv_h     = rtems_filesystem_default_readv,
 	.writev_h    = rtems_filesystem_default_writev
@@ -2924,6 +2926,7 @@ struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers = {
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fcntl_h     = rtems_filesystem_default_fcntl,
 	.kqfilter_h  = rtems_filesystem_default_kqfilter,
+	.mmap_h      = rtems_filesystem_default_mmap,
 	.poll_h      = rtems_filesystem_default_poll,
 	.readv_h     = rtems_filesystem_default_readv,
 	.writev_h    = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
index a8ba126..3c69eaa 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
@@ -195,6 +195,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_device_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h     = rtems_filesystem_default_fcntl,
   .kqfilter_h  = rtems_filesystem_default_kqfilter,
+  .mmap_h      = rtems_filesystem_default_mmap,
   .poll_h      = rtems_filesystem_default_poll,
   .readv_h     = rtems_filesystem_default_readv,
   .writev_h    = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c
index df0e639..ab4e56f 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c
@@ -164,6 +164,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_dir_handlers = {
   .fdatasync_h = rtems_rfs_rtems_fdatasync,
   .fcntl_h     = rtems_filesystem_default_fcntl,
   .kqfilter_h  = rtems_filesystem_default_kqfilter,
+  .mmap_h      = rtems_filesystem_default_mmap,
   .poll_h      = rtems_filesystem_default_poll,
   .readv_h     = rtems_filesystem_default_readv,
   .writev_h    = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
index 31df78a..99782db 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
@@ -348,6 +348,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_file_handlers = {
   .fdatasync_h = rtems_rfs_rtems_fdatasync,
   .fcntl_h     = rtems_filesystem_default_fcntl,
   .kqfilter_h  = rtems_filesystem_default_kqfilter,
+  .mmap_h      = rtems_filesystem_default_mmap,
   .poll_h      = rtems_filesystem_default_poll,
   .readv_h     = rtems_filesystem_default_readv,
   .writev_h    = rtems_filesystem_default_writev
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
index 5ce526a..45455eb 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
@@ -701,6 +701,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_link_handlers =
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h     = rtems_filesystem_default_fcntl,
   .kqfilter_h  = rtems_filesystem_default_kqfilter,
+  .mmap_h      = rtems_filesystem_default_mmap,
   .poll_h      = rtems_filesystem_default_poll,
   .readv_h     = rtems_filesystem_default_readv,
   .writev_h    = rtems_filesystem_default_writev
diff --git a/cpukit/libnetworking/lib/ftpfs.c b/cpukit/libnetworking/lib/ftpfs.c
index e016cae..912ec82 100644
--- a/cpukit/libnetworking/lib/ftpfs.c
+++ b/cpukit/libnetworking/lib/ftpfs.c
@@ -1404,6 +1404,7 @@ static const rtems_filesystem_file_handlers_r rtems_ftpfs_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
@@ -1422,6 +1423,7 @@ static const rtems_filesystem_file_handlers_r rtems_ftpfs_root_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = rtems_filesystem_default_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libnetworking/lib/tftpDriver.c b/cpukit/libnetworking/lib/tftpDriver.c
index 52236be..1a5823b 100644
--- a/cpukit/libnetworking/lib/tftpDriver.c
+++ b/cpukit/libnetworking/lib/tftpDriver.c
@@ -1053,6 +1053,7 @@ static const rtems_filesystem_file_handlers_r rtems_tftp_handlers = {
    .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
    .fcntl_h = rtems_filesystem_default_fcntl,
    .kqfilter_h = rtems_filesystem_default_kqfilter,
+   .mmap_h = rtems_filesystem_default_mmap,
    .poll_h = rtems_filesystem_default_poll,
    .readv_h = rtems_filesystem_default_readv,
    .writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/libnetworking/rtems/rtems_syscall.c b/cpukit/libnetworking/rtems/rtems_syscall.c
index 6bef21a..29b2b4c 100644
--- a/cpukit/libnetworking/rtems/rtems_syscall.c
+++ b/cpukit/libnetworking/rtems/rtems_syscall.c
@@ -822,6 +822,7 @@ static const rtems_filesystem_file_handlers_r socket_handlers = {
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fcntl_h = rtems_bsdnet_fcntl,
 	.kqfilter_h = rtems_filesystem_default_kqfilter,
+	.mmap_h = rtems_filesystem_default_mmap,
 	.poll_h = rtems_filesystem_default_poll,
 	.readv_h = rtems_filesystem_default_readv,
 	.writev_h = rtems_filesystem_default_writev
diff --git a/cpukit/posix/src/mmap.c b/cpukit/posix/src/mmap.c
index 5b6ac2e..d9b663d 100644
--- a/cpukit/posix/src/mmap.c
+++ b/cpukit/posix/src/mmap.c
@@ -5,6 +5,7 @@
 /*
  * Copyright (c) 2012 Chris Johns (chrisj at rtems.org)
  * Copyright (c) 2017 Gedare Bloom (gedare at rtems.org)
+ * Copyright (c) 2017 Kevin kirspel (kirspkt at gmail.com)
  *
  * The license and distribution terms for this file may be
  * found in the file LICENSE in this distribution or at
@@ -107,30 +108,6 @@ bool mmap_mappings_lock_release(
   return true;
 }
 
-/* Helper function only gets called for mmap mappings of shared memory objects
- * with the MAP_SHARED flag.
- */
-static void *shm_mmap( rtems_libio_t *iop, size_t len, int prot, off_t off)
-{
-  POSIX_Shm_Control *shm = iop_to_shm( iop );
-  void *m;
-
-  _Objects_Allocator_lock();
-
-  m = (*shm->shm_object.ops->object_mmap)( &shm->shm_object, len, prot, off);
-  if ( m != NULL ) {
-    /* Keep a reference in the shared memory to prevent its removal. */
-    ++shm->reference_count;
-
-    /* Update atime */
-    _POSIX_Shm_Update_atime(shm);
-  }
-
-  _Objects_Allocator_unlock();
-
-  return m;
-}
-
 void *mmap(
   void *addr, size_t len, int prot, int flags, int fildes, off_t off
 )
@@ -140,37 +117,25 @@ void *mmap(
   ssize_t         r;
   rtems_libio_t  *iop;
   bool            map_fixed;
+  bool            map_anonymous;
+  bool            map_shared;
+  bool            map_private;
+  int             err;
 
   map_fixed = (flags & MAP_FIXED) == MAP_FIXED;
+  map_anonymous = (flags & MAP_ANON) == MAP_ANON;
+  map_shared = (flags & MAP_SHARED) == MAP_SHARED;
+  map_private = (flags & MAP_PRIVATE) == MAP_PRIVATE;
 
   /* Clear errno. */
   errno = 0;
-
-  /*
-   * Get a stat of the file to get the dev + inode number and to make sure the
-   * fd is ok. The normal libio calls cannot be used because we need to return
-   * MAP_FAILED on error and they return -1 directly without coming back to
-   * here.
-   */
-  if ( fstat( fildes, &sb ) < 0 ) {
-    errno = EBADF;
-    return MAP_FAILED;
-  }
-
-  /* fstat ensures we have a good file descriptor. Hold on to iop. */
-  iop = rtems_libio_iop( fildes );
+  iop = NULL;
 
   if ( len == 0 ) {
     errno = EINVAL;
     return MAP_FAILED;
   }
 
-  /* Check the type of file we have and make sure it is supported. */
-  if ( S_ISDIR( sb.st_mode ) || S_ISLNK( sb.st_mode )) {
-    errno = ENODEV;
-    return MAP_FAILED;
-  }
-
   /*
    * We can provide read, write and execute because the memory in RTEMS does
    * not normally have protections but we cannot hide access to memory.
@@ -180,17 +145,6 @@ void *mmap(
     return MAP_FAILED;
   }
 
-  /* Either MAP_SHARED or MAP_PRIVATE must be defined, but not both */
-  if ( (flags & MAP_SHARED) == MAP_SHARED ) {
-    if ( (flags & MAP_PRIVATE) == MAP_PRIVATE ) {
-      errno = EINVAL;
-      return MAP_FAILED;
-    }
-  } else if ( (flags & MAP_PRIVATE) != MAP_PRIVATE ) {
-    errno = EINVAL;
-    return MAP_FAILED;
-  }
-
   /*
    * We can not normally provide restriction of write access. Reject any
    * attempt to map without write permission, since we are not able to
@@ -201,27 +155,104 @@ void *mmap(
     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;
+  /*
+   * Anonymous mappings must have file descriptor set to -1 and the offset
+   * set to 0. Shared mappings are not supported with Anonymous mappings at
+   * this time
+   */
+  if ( map_anonymous && (fildes != -1 || off != 0 || map_shared) ) {
+    errno = EINVAL;
     return MAP_FAILED;
   }
 
   /*
-   * Check to see if the mapping is valid for other file/object types.
-   * Does this satisfy for devices?
+   * If MAP_ANON is declared without MAP_PRIVATE or MAP_SHARED,
+   * force MAP_PRIVATE
    */
-  if ( sb.st_size < off + len ) {
-    errno = ENXIO;
+  if ( map_anonymous && !map_private && !map_shared ) {
+    flags |= MAP_PRIVATE;
+    map_private = true;
+  }
+
+  /* Check for supported flags */
+  if ((flags & ~(MAP_SHARED | MAP_PRIVATE | MAP_FIXED | MAP_ANON)) != 0) {
+    errno = EINVAL;
     return MAP_FAILED;
   }
 
-  /* 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 ) {
+  /* Either MAP_SHARED or MAP_PRIVATE must be defined, but not both */
+  if ( map_shared ) {
+    if ( map_private ) {
+      errno = EINVAL;
+      return MAP_FAILED;
+    }
+  } else if ( !map_private ) {
+    errno = EINVAL;
+    return MAP_FAILED;
+  }
+
+  /* Check for illegal addresses. Watch out for address wrap. */
+  if ( map_fixed ) {
+    if ((uintptr_t)addr & PAGE_MASK) {
+      errno = EINVAL;
+      return MAP_FAILED;
+    }
+    if ( addr == NULL ) {
+      errno = EINVAL;
+      return MAP_FAILED;
+    }
+    if (addr + len < addr) {
+      errno = EINVAL;
+      return MAP_FAILED;
+    }
+  }
+
+  if ( !map_anonymous ) {
+    /*
+     * Get a stat of the file to get the dev + inode number and to make sure the
+     * fd is ok. The normal libio calls cannot be used because we need to return
+     * MAP_FAILED on error and they return -1 directly without coming back to
+     * here.
+     */
+    if ( fstat( fildes, &sb ) < 0 ) {
+      errno = EBADF;
+      return MAP_FAILED;
+    }
+
+    /* fstat ensures we have a good file descriptor. Hold on to iop. */
+    iop = rtems_libio_iop( fildes );
+
+    /* Check the type of file we have and make sure it is supported. */
+    if ( S_ISDIR( sb.st_mode ) || S_ISLNK( sb.st_mode )) {
+      errno = ENODEV;
+      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 ( !S_ISCHR( sb.st_mode ) && sb.st_size < off + len ) {
+      errno = ENXIO;
+      return MAP_FAILED;
+    }
+
+    /* 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 ) {
+        return MAP_FAILED;
+      }
+    }
+
+    /* cdevs do not provide private mappings of any kind. */
+    if ( S_ISCHR( sb.st_mode ) && map_private ) {
+      errno = EINVAL;
       return MAP_FAILED;
     }
   }
@@ -230,42 +261,37 @@ void *mmap(
   mapping = malloc( sizeof( mmap_mapping ));
   if ( !mapping ) {
     errno = ENOMEM;
-    return NULL;
+    return MAP_FAILED;
   }
   memset( mapping, 0, sizeof( mmap_mapping ));
   mapping->len = len;
   mapping->flags = flags;
   mapping->iop = iop;
 
-  /*
-   * HACK: We should have a better generic way to distinguish between
-   * shm objects and other mmap'd files. We need to know at munmap time
-   * if the mapping is to a shared memory object in order to refcnt shms.
-   * We could do this by providing mmap in the file operations if needed.
-   */
-  if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ||
-       S_ISCHR( sb.st_mode ) || S_ISFIFO( sb.st_mode ) ||
-       S_ISSOCK( sb.st_mode ) ) {
-    mapping->is_shared_shm = false;
+  if ( !map_anonymous ) {
+    /*
+     * HACK: We should have a better generic way to distinguish between
+     * shm objects and other mmap'd files. We need to know at munmap time
+     * if the mapping is to a shared memory object in order to refcnt shms.
+     * We could do this by providing mmap in the file operations if needed.
+     */
+    if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ||
+         S_ISCHR( sb.st_mode ) || S_ISFIFO( sb.st_mode ) ||
+         S_ISSOCK( sb.st_mode ) ) {
+      mapping->is_shared_shm = false;
+    } else {
+      mapping->is_shared_shm = true;
+    }
   } else {
-    mapping->is_shared_shm = true;
-  }
-
-  /*
-   * MAP_SHARED currently is only supported for shared memory objects.
-   */
-  if ( (MAP_SHARED == (flags & MAP_SHARED)) && (mapping->is_shared_shm == false) ) {
-    free( mapping );
-    errno = ENOTSUP;
-    return MAP_FAILED;
+    mapping->is_shared_shm = false;
   }
 
   if ( map_fixed ) {
     mapping->addr = addr;
-  } else if ( MAP_PRIVATE == (flags & MAP_PRIVATE) ) {
+  } else if ( map_private ) {
     /* private mappings of shared memory do not need special treatment. */
     mapping->is_shared_shm = false;
-    mapping->addr = malloc( len );
+    posix_memalign( &mapping->addr, PAGE_SIZE, len );
     if ( !mapping->addr ) {
       free( mapping );
       errno = ENOMEM;
@@ -306,32 +332,43 @@ void *mmap(
   }
 
   /* Populate the data */
-  if ( MAP_PRIVATE == (flags & MAP_PRIVATE) ) {
-    /*
-     * Use read() for private mappings. This updates atime as needed.
-     * Changes to the underlying object will NOT be reflected in the mapping.
-     * The underlying object can be removed while the mapping exists.
-     */
-    r = read( fildes, mapping->addr, len );
+  if ( map_private ) {
+    if ( !map_anonymous ) {
+      /*
+       * Use read() for private mappings. This updates atime as needed.
+       * Changes to the underlying object will NOT be reflected in the mapping.
+       * The underlying object can be removed while the mapping exists.
+       */
+      r = read( fildes, mapping->addr, len );
 
-    if ( r != len ) {
-      mmap_mappings_lock_release( );
-      if ( !map_fixed ) {
-        free( mapping->addr );
+      if ( r != len ) {
+        mmap_mappings_lock_release( );
+        if ( !map_fixed ) {
+          free( mapping->addr );
+        }
+        free( mapping );
+        errno = ENXIO;
+        return MAP_FAILED;
       }
+    } else if ( !map_fixed ) {
+      memset( mapping->addr, 0, len );
+    }
+  } else if ( map_shared ) {
+    err = (*iop->pathinfo.handlers->mmap_h)(
+        iop, &mapping->addr, len, prot, off );
+    if ( err != 0 ) {
+      mmap_mappings_lock_release( );
       free( mapping );
-      errno = ENXIO;
       return MAP_FAILED;
     }
-  } else if ( MAP_SHARED == (flags & MAP_SHARED) ) {
-    /* Currently only shm objects can be MAP_SHARED. */
-    mapping->addr = shm_mmap(iop, len, prot, off);
   }
 
-  /* 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_libio_increment_mapping_refcnt(iop);
+  if ( iop != NULL ) {
+    /* 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_libio_increment_mapping_refcnt(iop);
+  }
 
   rtems_chain_append( &mmap_mappings, &mapping->node );
 
diff --git a/cpukit/posix/src/munmap.c b/cpukit/posix/src/munmap.c
index 323a24e..2d812ae 100644
--- a/cpukit/posix/src/munmap.c
+++ b/cpukit/posix/src/munmap.c
@@ -46,6 +46,12 @@ int munmap(void *addr, size_t len)
     return -1;
   }
 
+  /* Check for illegal addresses. Watch out for address wrap. */
+  if (addr + len < addr) {
+    errno = EINVAL;
+    return -1;
+  }
+
   /*
    * Obtain the mmap lock. Sets errno on failure.
    */
@@ -63,9 +69,11 @@ int munmap(void *addr, size_t len)
       if ( mapping->is_shared_shm == true ) {
         shm_munmap(mapping->iop);
       }
-      refcnt = rtems_libio_decrement_mapping_refcnt(mapping->iop);
-      if ( refcnt == 0 ) {
-        rtems_libio_check_deferred_free(mapping->iop);
+      if ( mapping->iop != NULL ) {
+        refcnt = rtems_libio_decrement_mapping_refcnt(mapping->iop);
+        if ( refcnt == 0 ) {
+          rtems_libio_check_deferred_free(mapping->iop);
+        }
       }
       /* only free the mapping address for non-fixed mapping */
       if (( mapping->flags & MAP_FIXED ) != MAP_FIXED ) {
diff --git a/cpukit/posix/src/shmopen.c b/cpukit/posix/src/shmopen.c
index fa1027e..e729f9b 100644
--- a/cpukit/posix/src/shmopen.c
+++ b/cpukit/posix/src/shmopen.c
@@ -106,6 +106,35 @@ static int shm_close( rtems_libio_t *iop )
   return 0;
 }
 
+static int shm_mmap(
+  rtems_libio_t *iop,
+  void** addr,
+  size_t len,
+  int prot,
+  off_t off
+)
+{
+  POSIX_Shm_Control *shm = iop_to_shm( iop );
+
+  _Objects_Allocator_lock();
+
+  *addr = (*shm->shm_object.ops->object_mmap)( &shm->shm_object, len, prot, off);
+  if ( *addr != NULL ) {
+    /* Keep a reference in the shared memory to prevent its removal. */
+    ++shm->reference_count;
+
+    /* Update atime */
+    _POSIX_Shm_Update_atime(shm);
+  } else {
+    _Objects_Allocator_unlock();
+    rtems_set_errno_and_return_minus_one( ENOMEM );
+  }
+
+  _Objects_Allocator_unlock();
+
+  return 0;
+}
+
 static inline POSIX_Shm_Control *shm_allocate(
   const char *name_arg,
   size_t name_len,
@@ -275,6 +304,7 @@ static const rtems_filesystem_file_handlers_r shm_handlers = {
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fcntl_h = rtems_filesystem_default_fcntl,
   .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .mmap_h = shm_mmap,
   .poll_h = rtems_filesystem_default_poll,
   .readv_h = rtems_filesystem_default_readv,
   .writev_h = rtems_filesystem_default_writev
-- 
1.9.1



More information about the devel mailing list