Changeset c6bb1c33 in rtems


Ignore:
Timestamp:
Jun 29, 2017, 2:36:43 PM (2 years ago)
Author:
Kevin Kirspel <kevin-kirspel@…>
Branches:
master
Children:
1549beb
Parents:
e19da87
git-author:
Kevin Kirspel <kevin-kirspel@…> (06/29/17 14:36:43)
git-committer:
Gedare Bloom <gedare@…> (07/14/17 20:04:05)
Message:

posix/mmap: Add support for file handler and MAP_ANON

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

Location:
cpukit
Files:
1 added
33 edited

Legend:

Unmodified
Added
Removed
  • cpukit/dev/i2c/i2c-bus.c

    re19da87 rc6bb1c33  
    219219  .fcntl_h = rtems_filesystem_default_fcntl,
    220220  .kqfilter_h = rtems_filesystem_default_kqfilter,
     221  .mmap_h = rtems_filesystem_default_mmap,
    221222  .poll_h = rtems_filesystem_default_poll,
    222223  .readv_h = rtems_filesystem_default_readv,
  • cpukit/dev/i2c/i2c-dev.c

    re19da87 rc6bb1c33  
    116116  .fcntl_h = rtems_filesystem_default_fcntl,
    117117  .kqfilter_h = rtems_filesystem_default_kqfilter,
     118  .mmap_h = rtems_filesystem_default_mmap,
    118119  .poll_h = rtems_filesystem_default_poll,
    119120  .readv_h = rtems_filesystem_default_readv,
  • cpukit/dev/spi/spi-bus.c

    re19da87 rc6bb1c33  
    236236  .fcntl_h = rtems_filesystem_default_fcntl,
    237237  .kqfilter_h = rtems_filesystem_default_kqfilter,
     238  .mmap_h = rtems_filesystem_default_mmap,
    238239  .poll_h = rtems_filesystem_default_poll,
    239240  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libblock/src/blkdev-imfs.c

    re19da87 rc6bb1c33  
    223223  .fcntl_h = rtems_filesystem_default_fcntl,
    224224  .kqfilter_h = rtems_filesystem_default_kqfilter,
     225  .mmap_h = rtems_filesystem_default_mmap,
    225226  .poll_h = rtems_filesystem_default_poll,
    226227  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libcsupport/include/rtems/libio.h

    re19da87 rc6bb1c33  
    978978
    979979/**
     980 * @brief MMAP support.
     981 *
     982 * @param[in, out] iop The IO pointer.
     983 * @param[in, out] addr The starting address of the mapped memory.
     984 * @param[in] len The maximum number of bytes to map.
     985 * @param[in] prot The desired memory protection.
     986 * @param[in] off The offset within the file descriptor to map.
     987 *
     988 * @retval 0 Successful operation.
     989 * @retval error An error occurred.  This is usually EINVAL.
     990 *
     991 * @see rtems_filesystem_default_mmap().
     992 */
     993typedef int (*rtems_filesystem_mmap_t)(
     994  rtems_libio_t *iop,
     995  void **addr,
     996  size_t len,
     997  int prot,
     998  off_t off
     999);
     1000
     1001/**
    9801002 * @brief File system node operations table.
    9811003 */
     
    9961018  rtems_filesystem_readv_t readv_h;
    9971019  rtems_filesystem_writev_t writev_h;
     1020  rtems_filesystem_mmap_t mmap_h;
    9981021};
    9991022
     
    12151238  rtems_libio_t *iop,
    12161239  struct knote *kn
     1240);
     1241
     1242/**
     1243 * @brief Default MMAP handler.
     1244 *
     1245 * @retval ENOTSUP Always.
     1246 *
     1247 * @see rtems_filesystem_mmap_t.
     1248 */
     1249int rtems_filesystem_default_mmap(
     1250  rtems_libio_t *iop,
     1251  void **addr,
     1252  size_t len,
     1253  int prot,
     1254  off_t off
    12171255);
    12181256
  • cpukit/libcsupport/include/rtems/termiostypes.h

    re19da87 rc6bb1c33  
    566566
    567567/**
     568 * @brief Termios mmap() filter filesystem node handler
     569 *
     570 * Real implementation is provided by libbsd.
     571 */
     572int rtems_termios_mmap(
     573  rtems_libio_t *iop,
     574  void         **addr,
     575  size_t         len,
     576  int            prot,
     577  off_t          off
     578);
     579
     580/**
    568581 * @brief Termios poll() filesystem node handler.
    569582 *
  • cpukit/libcsupport/src/__usrenv.c

    re19da87 rc6bb1c33  
    5757  .fcntl_h = rtems_filesystem_default_fcntl,
    5858  .kqfilter_h = rtems_filesystem_default_kqfilter,
     59  .mmap_h = rtems_filesystem_default_mmap,
    5960  .poll_h = rtems_filesystem_default_poll,
    6061  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libcsupport/src/termios.c

    re19da87 rc6bb1c33  
    22132213  .fcntl_h = rtems_filesystem_default_fcntl,
    22142214  .kqfilter_h = rtems_termios_kqfilter,
     2215  .mmap_h = rtems_termios_mmap,
    22152216  .poll_h = rtems_termios_poll,
    22162217  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/Makefile.am

    re19da87 rc6bb1c33  
    3434    src/defaults/default_handlers.c src/defaults/default_ops.c
    3535libdefaultfs_a_SOURCES += src/defaults/default_kqfilter.c
     36libdefaultfs_a_SOURCES += src/defaults/default_mmap.c
    3637libdefaultfs_a_SOURCES += src/defaults/default_poll.c
    3738libdefaultfs_a_SOURCES += src/defaults/default_readv.c
  • cpukit/libfs/src/defaults/default_handlers.c

    re19da87 rc6bb1c33  
    3535  .fcntl_h = rtems_filesystem_default_fcntl,
    3636  .kqfilter_h = rtems_filesystem_default_kqfilter,
     37  .mmap_h = rtems_filesystem_default_mmap,
    3738  .poll_h = rtems_filesystem_default_poll,
    3839  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/devfs/devfs_init.c

    re19da87 rc6bb1c33  
    5353  .fcntl_h = rtems_filesystem_default_fcntl,
    5454  .kqfilter_h = rtems_filesystem_default_kqfilter,
     55  .mmap_h = rtems_filesystem_default_mmap,
    5556  .poll_h = rtems_filesystem_default_poll,
    5657  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/dosfs/msdos_handlers_dir.c

    re19da87 rc6bb1c33  
    3535  .fcntl_h = rtems_filesystem_default_fcntl,
    3636  .kqfilter_h = rtems_filesystem_default_kqfilter,
     37  .mmap_h = rtems_filesystem_default_mmap,
    3738  .poll_h = rtems_filesystem_default_poll,
    3839  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/dosfs/msdos_handlers_file.c

    re19da87 rc6bb1c33  
    3535  .fcntl_h = rtems_filesystem_default_fcntl,
    3636  .kqfilter_h = rtems_filesystem_default_kqfilter,
     37  .mmap_h = rtems_filesystem_default_mmap,
    3738  .poll_h = rtems_filesystem_default_poll,
    3839  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/imfs/imfs_dir_default.c

    re19da87 rc6bb1c33  
    131131  .fcntl_h = rtems_filesystem_default_fcntl,
    132132  .kqfilter_h = rtems_filesystem_default_kqfilter,
     133  .mmap_h = rtems_filesystem_default_mmap,
    133134  .poll_h = rtems_filesystem_default_poll,
    134135  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/imfs/imfs_dir_minimal.c

    re19da87 rc6bb1c33  
    3333  .fcntl_h = rtems_filesystem_default_fcntl,
    3434  .kqfilter_h = rtems_filesystem_default_kqfilter,
     35  .mmap_h = rtems_filesystem_default_mmap,
    3536  .poll_h = rtems_filesystem_default_poll,
    3637  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/imfs/imfs_fifo.c

    re19da87 rc6bb1c33  
    128128  .fcntl_h = rtems_filesystem_default_fcntl,
    129129  .kqfilter_h = rtems_filesystem_default_kqfilter,
     130  .mmap_h = rtems_filesystem_default_mmap,
    130131  .poll_h = rtems_filesystem_default_poll,
    131132  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/imfs/imfs_handlers_device.c

    re19da87 rc6bb1c33  
    4646  .fcntl_h = rtems_filesystem_default_fcntl,
    4747  .kqfilter_h = rtems_filesystem_default_kqfilter,
     48  .mmap_h = rtems_filesystem_default_mmap,
    4849  .poll_h = rtems_filesystem_default_poll,
    4950  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/imfs/imfs_linfile.c

    re19da87 rc6bb1c33  
    8888  .fcntl_h = rtems_filesystem_default_fcntl,
    8989  .kqfilter_h = rtems_filesystem_default_kqfilter,
     90  .mmap_h = rtems_filesystem_default_mmap,
    9091  .poll_h = rtems_filesystem_default_poll,
    9192  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/imfs/imfs_link.c

    re19da87 rc6bb1c33  
    9494  .fcntl_h = rtems_filesystem_default_fcntl,
    9595  .kqfilter_h = rtems_filesystem_default_kqfilter,
     96  .mmap_h = rtems_filesystem_default_mmap,
    9697  .poll_h = rtems_filesystem_default_poll,
    9798  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/imfs/imfs_memfile.c

    re19da87 rc6bb1c33  
    845845  .fcntl_h = rtems_filesystem_default_fcntl,
    846846  .kqfilter_h = rtems_filesystem_default_kqfilter,
     847  .mmap_h = rtems_filesystem_default_mmap,
    847848  .poll_h = rtems_filesystem_default_poll,
    848849  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/imfs/imfs_symlink.c

    re19da87 rc6bb1c33  
    9696  .fcntl_h = rtems_filesystem_default_fcntl,
    9797  .kqfilter_h = rtems_filesystem_default_kqfilter,
     98  .mmap_h = rtems_filesystem_default_mmap,
    9899  .poll_h = rtems_filesystem_default_poll,
    99100  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/jffs2/src/fs-rtems.c

    re19da87 rc6bb1c33  
    607607        .fcntl_h = rtems_filesystem_default_fcntl,
    608608        .kqfilter_h = rtems_filesystem_default_kqfilter,
     609        .mmap_h = rtems_filesystem_default_mmap,
    609610        .poll_h = rtems_filesystem_default_poll,
    610611        .readv_h = rtems_filesystem_default_readv,
     
    749750        .fcntl_h = rtems_filesystem_default_fcntl,
    750751        .kqfilter_h = rtems_filesystem_default_kqfilter,
     752        .mmap_h = rtems_filesystem_default_mmap,
    751753        .poll_h = rtems_filesystem_default_poll,
    752754        .readv_h = rtems_filesystem_default_readv,
     
    767769        .fcntl_h = rtems_filesystem_default_fcntl,
    768770        .kqfilter_h = rtems_filesystem_default_kqfilter,
     771        .mmap_h = rtems_filesystem_default_mmap,
    769772        .poll_h = rtems_filesystem_default_poll,
    770773        .readv_h = rtems_filesystem_default_readv,
  • cpukit/libfs/src/nfsclient/src/nfs.c

    re19da87 rc6bb1c33  
    28852885        .fcntl_h     = rtems_filesystem_default_fcntl,
    28862886        .kqfilter_h  = rtems_filesystem_default_kqfilter,
     2887        .mmap_h      = rtems_filesystem_default_mmap,
    28872888        .poll_h      = rtems_filesystem_default_poll,
    28882889        .readv_h     = rtems_filesystem_default_readv,
     
    29052906        .fcntl_h     = rtems_filesystem_default_fcntl,
    29062907        .kqfilter_h  = rtems_filesystem_default_kqfilter,
     2908        .mmap_h      = rtems_filesystem_default_mmap,
    29072909        .poll_h      = rtems_filesystem_default_poll,
    29082910        .readv_h     = rtems_filesystem_default_readv,
     
    29252927        .fcntl_h     = rtems_filesystem_default_fcntl,
    29262928        .kqfilter_h  = rtems_filesystem_default_kqfilter,
     2929        .mmap_h      = rtems_filesystem_default_mmap,
    29272930        .poll_h      = rtems_filesystem_default_poll,
    29282931        .readv_h     = rtems_filesystem_default_readv,
  • cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c

    re19da87 rc6bb1c33  
    196196  .fcntl_h     = rtems_filesystem_default_fcntl,
    197197  .kqfilter_h  = rtems_filesystem_default_kqfilter,
     198  .mmap_h      = rtems_filesystem_default_mmap,
    198199  .poll_h      = rtems_filesystem_default_poll,
    199200  .readv_h     = rtems_filesystem_default_readv,
  • cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c

    re19da87 rc6bb1c33  
    165165  .fcntl_h     = rtems_filesystem_default_fcntl,
    166166  .kqfilter_h  = rtems_filesystem_default_kqfilter,
     167  .mmap_h      = rtems_filesystem_default_mmap,
    167168  .poll_h      = rtems_filesystem_default_poll,
    168169  .readv_h     = rtems_filesystem_default_readv,
  • cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c

    re19da87 rc6bb1c33  
    349349  .fcntl_h     = rtems_filesystem_default_fcntl,
    350350  .kqfilter_h  = rtems_filesystem_default_kqfilter,
     351  .mmap_h      = rtems_filesystem_default_mmap,
    351352  .poll_h      = rtems_filesystem_default_poll,
    352353  .readv_h     = rtems_filesystem_default_readv,
  • cpukit/libfs/src/rfs/rtems-rfs-rtems.c

    re19da87 rc6bb1c33  
    702702  .fcntl_h     = rtems_filesystem_default_fcntl,
    703703  .kqfilter_h  = rtems_filesystem_default_kqfilter,
     704  .mmap_h      = rtems_filesystem_default_mmap,
    704705  .poll_h      = rtems_filesystem_default_poll,
    705706  .readv_h     = rtems_filesystem_default_readv,
  • cpukit/libnetworking/lib/ftpfs.c

    re19da87 rc6bb1c33  
    14051405  .fcntl_h = rtems_filesystem_default_fcntl,
    14061406  .kqfilter_h = rtems_filesystem_default_kqfilter,
     1407  .mmap_h = rtems_filesystem_default_mmap,
    14071408  .poll_h = rtems_filesystem_default_poll,
    14081409  .readv_h = rtems_filesystem_default_readv,
     
    14231424  .fcntl_h = rtems_filesystem_default_fcntl,
    14241425  .kqfilter_h = rtems_filesystem_default_kqfilter,
     1426  .mmap_h = rtems_filesystem_default_mmap,
    14251427  .poll_h = rtems_filesystem_default_poll,
    14261428  .readv_h = rtems_filesystem_default_readv,
  • cpukit/libnetworking/lib/tftpDriver.c

    re19da87 rc6bb1c33  
    10541054   .fcntl_h = rtems_filesystem_default_fcntl,
    10551055   .kqfilter_h = rtems_filesystem_default_kqfilter,
     1056   .mmap_h = rtems_filesystem_default_mmap,
    10561057   .poll_h = rtems_filesystem_default_poll,
    10571058   .readv_h = rtems_filesystem_default_readv,
  • cpukit/libnetworking/rtems/rtems_syscall.c

    re19da87 rc6bb1c33  
    823823        .fcntl_h = rtems_bsdnet_fcntl,
    824824        .kqfilter_h = rtems_filesystem_default_kqfilter,
     825        .mmap_h = rtems_filesystem_default_mmap,
    825826        .poll_h = rtems_filesystem_default_poll,
    826827        .readv_h = rtems_filesystem_default_readv,
  • cpukit/posix/src/mmap.c

    re19da87 rc6bb1c33  
    66 * Copyright (c) 2012 Chris Johns (chrisj@rtems.org)
    77 * Copyright (c) 2017 Gedare Bloom (gedare@rtems.org)
     8 * Copyright (c) 2017 Kevin kirspel (kirspkt@gmail.com)
    89 *
    910 * The license and distribution terms for this file may be
     
    108109}
    109110
    110 /* Helper function only gets called for mmap mappings of shared memory objects
    111  * with the MAP_SHARED flag.
    112  */
    113 static void *shm_mmap( rtems_libio_t *iop, size_t len, int prot, off_t off)
    114 {
    115   POSIX_Shm_Control *shm = iop_to_shm( iop );
    116   void *m;
    117 
    118   _Objects_Allocator_lock();
    119 
    120   m = (*shm->shm_object.ops->object_mmap)( &shm->shm_object, len, prot, off);
    121   if ( m != NULL ) {
    122     /* Keep a reference in the shared memory to prevent its removal. */
    123     ++shm->reference_count;
    124 
    125     /* Update atime */
    126     _POSIX_Shm_Update_atime(shm);
    127   }
    128 
    129   _Objects_Allocator_unlock();
    130 
    131   return m;
    132 }
    133 
    134111void *mmap(
    135112  void *addr, size_t len, int prot, int flags, int fildes, off_t off
     
    141118  rtems_libio_t  *iop;
    142119  bool            map_fixed;
     120  bool            map_anonymous;
     121  bool            map_shared;
     122  bool            map_private;
     123  int             err;
    143124
    144125  map_fixed = (flags & MAP_FIXED) == MAP_FIXED;
     126  map_anonymous = (flags & MAP_ANON) == MAP_ANON;
     127  map_shared = (flags & MAP_SHARED) == MAP_SHARED;
     128  map_private = (flags & MAP_PRIVATE) == MAP_PRIVATE;
    145129
    146130  /* Clear errno. */
    147131  errno = 0;
    148 
    149   /*
    150    * Get a stat of the file to get the dev + inode number and to make sure the
    151    * fd is ok. The normal libio calls cannot be used because we need to return
    152    * MAP_FAILED on error and they return -1 directly without coming back to
    153    * here.
    154    */
    155   if ( fstat( fildes, &sb ) < 0 ) {
    156     errno = EBADF;
    157     return MAP_FAILED;
    158   }
    159 
    160   /* fstat ensures we have a good file descriptor. Hold on to iop. */
    161   iop = rtems_libio_iop( fildes );
     132  iop = NULL;
    162133
    163134  if ( len == 0 ) {
    164135    errno = EINVAL;
    165     return MAP_FAILED;
    166   }
    167 
    168   /* Check the type of file we have and make sure it is supported. */
    169   if ( S_ISDIR( sb.st_mode ) || S_ISLNK( sb.st_mode )) {
    170     errno = ENODEV;
    171136    return MAP_FAILED;
    172137  }
     
    178143  if ( prot == PROT_NONE ) {
    179144    errno = ENOTSUP;
    180     return MAP_FAILED;
    181   }
    182 
    183   /* Either MAP_SHARED or MAP_PRIVATE must be defined, but not both */
    184   if ( (flags & MAP_SHARED) == MAP_SHARED ) {
    185     if ( (flags & MAP_PRIVATE) == MAP_PRIVATE ) {
    186       errno = EINVAL;
    187       return MAP_FAILED;
    188     }
    189   } else if ( (flags & MAP_PRIVATE) != MAP_PRIVATE ) {
    190     errno = EINVAL;
    191145    return MAP_FAILED;
    192146  }
     
    202156  }
    203157
    204   /* Check to see if the mapping is valid for a regular file. */
    205   if ( S_ISREG( sb.st_mode )
    206   /* FIXME: Should this be using strict inequality (>) comparisons? It would
    207    * be valid to map a region exactly equal to the st_size, e.g. see below. */
    208        && (( off >= sb.st_size ) || (( off + len ) >= sb.st_size ))) {
    209     errno = EOVERFLOW;
    210     return MAP_FAILED;
    211   }
    212 
    213   /*
    214    * Check to see if the mapping is valid for other file/object types.
    215    * Does this satisfy for devices?
    216    */
    217   if ( sb.st_size < off + len ) {
    218     errno = ENXIO;
    219     return MAP_FAILED;
    220   }
    221 
    222   /* Do not seek on character devices, pipes, sockets, or memory objects. */
    223   if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ) {
    224     if ( lseek( fildes, off, SEEK_SET ) < 0 ) {
     158  /*
     159   * Anonymous mappings must have file descriptor set to -1 and the offset
     160   * set to 0. Shared mappings are not supported with Anonymous mappings at
     161   * this time
     162   */
     163  if ( map_anonymous && (fildes != -1 || off != 0 || map_shared) ) {
     164    errno = EINVAL;
     165    return MAP_FAILED;
     166  }
     167
     168  /*
     169   * If MAP_ANON is declared without MAP_PRIVATE or MAP_SHARED,
     170   * force MAP_PRIVATE
     171   */
     172  if ( map_anonymous && !map_private && !map_shared ) {
     173    flags |= MAP_PRIVATE;
     174    map_private = true;
     175  }
     176
     177  /* Check for supported flags */
     178  if ((flags & ~(MAP_SHARED | MAP_PRIVATE | MAP_FIXED | MAP_ANON)) != 0) {
     179    errno = EINVAL;
     180    return MAP_FAILED;
     181  }
     182
     183  /* Either MAP_SHARED or MAP_PRIVATE must be defined, but not both */
     184  if ( map_shared ) {
     185    if ( map_private ) {
     186      errno = EINVAL;
     187      return MAP_FAILED;
     188    }
     189  } else if ( !map_private ) {
     190    errno = EINVAL;
     191    return MAP_FAILED;
     192  }
     193
     194  /* Check for illegal addresses. Watch out for address wrap. */
     195  if ( map_fixed ) {
     196    if ((uintptr_t)addr & PAGE_MASK) {
     197      errno = EINVAL;
     198      return MAP_FAILED;
     199    }
     200    if ( addr == NULL ) {
     201      errno = EINVAL;
     202      return MAP_FAILED;
     203    }
     204    if (addr + len < addr) {
     205      errno = EINVAL;
     206      return MAP_FAILED;
     207    }
     208  }
     209
     210  if ( !map_anonymous ) {
     211    /*
     212     * Get a stat of the file to get the dev + inode number and to make sure the
     213     * fd is ok. The normal libio calls cannot be used because we need to return
     214     * MAP_FAILED on error and they return -1 directly without coming back to
     215     * here.
     216     */
     217    if ( fstat( fildes, &sb ) < 0 ) {
     218      errno = EBADF;
     219      return MAP_FAILED;
     220    }
     221
     222    /* fstat ensures we have a good file descriptor. Hold on to iop. */
     223    iop = rtems_libio_iop( fildes );
     224
     225    /* Check the type of file we have and make sure it is supported. */
     226    if ( S_ISDIR( sb.st_mode ) || S_ISLNK( sb.st_mode )) {
     227      errno = ENODEV;
     228      return MAP_FAILED;
     229    }
     230
     231    /* Check to see if the mapping is valid for a regular file. */
     232    if ( S_ISREG( sb.st_mode )
     233    /* FIXME: Should this be using strict inequality (>) comparisons? It would
     234     * be valid to map a region exactly equal to the st_size, e.g. see below. */
     235         && (( off >= sb.st_size ) || (( off + len ) >= sb.st_size ))) {
     236      errno = EOVERFLOW;
     237      return MAP_FAILED;
     238    }
     239
     240    /* Check to see if the mapping is valid for other file/object types. */
     241    if ( !S_ISCHR( sb.st_mode ) && sb.st_size < off + len ) {
     242      errno = ENXIO;
     243      return MAP_FAILED;
     244    }
     245
     246    /* Do not seek on character devices, pipes, sockets, or memory objects. */
     247    if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ) {
     248      if ( lseek( fildes, off, SEEK_SET ) < 0 ) {
     249        return MAP_FAILED;
     250      }
     251    }
     252
     253    /* cdevs do not provide private mappings of any kind. */
     254    if ( S_ISCHR( sb.st_mode ) && map_private ) {
     255      errno = EINVAL;
    225256      return MAP_FAILED;
    226257    }
     
    231262  if ( !mapping ) {
    232263    errno = ENOMEM;
    233     return NULL;
     264    return MAP_FAILED;
    234265  }
    235266  memset( mapping, 0, sizeof( mmap_mapping ));
     
    238269  mapping->iop = iop;
    239270
    240   /*
    241    * HACK: We should have a better generic way to distinguish between
    242    * shm objects and other mmap'd files. We need to know at munmap time
    243    * if the mapping is to a shared memory object in order to refcnt shms.
    244    * We could do this by providing mmap in the file operations if needed.
    245    */
    246   if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ||
    247        S_ISCHR( sb.st_mode ) || S_ISFIFO( sb.st_mode ) ||
    248        S_ISSOCK( sb.st_mode ) ) {
     271  if ( !map_anonymous ) {
     272    /*
     273     * HACK: We should have a better generic way to distinguish between
     274     * shm objects and other mmap'd files. We need to know at munmap time
     275     * if the mapping is to a shared memory object in order to refcnt shms.
     276     * We could do this by providing mmap in the file operations if needed.
     277     */
     278    if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ||
     279         S_ISCHR( sb.st_mode ) || S_ISFIFO( sb.st_mode ) ||
     280         S_ISSOCK( sb.st_mode ) ) {
     281      mapping->is_shared_shm = false;
     282    } else {
     283      mapping->is_shared_shm = true;
     284    }
     285  } else {
    249286    mapping->is_shared_shm = false;
    250   } else {
    251     mapping->is_shared_shm = true;
    252   }
    253 
    254   /*
    255    * MAP_SHARED currently is only supported for shared memory objects.
    256    */
    257   if ( (MAP_SHARED == (flags & MAP_SHARED)) && (mapping->is_shared_shm == false) ) {
    258     free( mapping );
    259     errno = ENOTSUP;
    260     return MAP_FAILED;
    261287  }
    262288
    263289  if ( map_fixed ) {
    264290    mapping->addr = addr;
    265   } else if ( MAP_PRIVATE == (flags & MAP_PRIVATE) ) {
     291  } else if ( map_private ) {
    266292    /* private mappings of shared memory do not need special treatment. */
    267293    mapping->is_shared_shm = false;
    268     mapping->addr = malloc( len );
     294    posix_memalign( &mapping->addr, PAGE_SIZE, len );
    269295    if ( !mapping->addr ) {
    270296      free( mapping );
     
    307333
    308334  /* Populate the data */
    309   if ( MAP_PRIVATE == (flags & MAP_PRIVATE) ) {
    310     /*
    311      * Use read() for private mappings. This updates atime as needed.
    312      * Changes to the underlying object will NOT be reflected in the mapping.
    313      * The underlying object can be removed while the mapping exists.
    314      */
    315     r = read( fildes, mapping->addr, len );
    316 
    317     if ( r != len ) {
     335  if ( map_private ) {
     336    if ( !map_anonymous ) {
     337      /*
     338       * Use read() for private mappings. This updates atime as needed.
     339       * Changes to the underlying object will NOT be reflected in the mapping.
     340       * The underlying object can be removed while the mapping exists.
     341       */
     342      r = read( fildes, mapping->addr, len );
     343
     344      if ( r != len ) {
     345        mmap_mappings_lock_release( );
     346        if ( !map_fixed ) {
     347          free( mapping->addr );
     348        }
     349        free( mapping );
     350        errno = ENXIO;
     351        return MAP_FAILED;
     352      }
     353    } else if ( !map_fixed ) {
     354      memset( mapping->addr, 0, len );
     355    }
     356  } else if ( map_shared ) {
     357    err = (*iop->pathinfo.handlers->mmap_h)(
     358        iop, &mapping->addr, len, prot, off );
     359    if ( err != 0 ) {
    318360      mmap_mappings_lock_release( );
    319       if ( !map_fixed ) {
    320         free( mapping->addr );
    321       }
    322361      free( mapping );
    323       errno = ENXIO;
    324       return MAP_FAILED;
    325     }
    326   } else if ( MAP_SHARED == (flags & MAP_SHARED) ) {
    327     /* Currently only shm objects can be MAP_SHARED. */
    328     mapping->addr = shm_mmap(iop, len, prot, off);
    329   }
    330 
    331   /* add an extra reference to the file associated with fildes that
    332    * is not removed by a subsequent close().  This reference shall be removed
    333    * when there are no more mappings to the file. */
    334   rtems_libio_increment_mapping_refcnt(iop);
     362      return MAP_FAILED;
     363    }
     364  }
     365
     366  if ( iop != NULL ) {
     367    /* add an extra reference to the file associated with fildes that
     368     * is not removed by a subsequent close().  This reference shall be removed
     369     * when there are no more mappings to the file. */
     370    rtems_libio_increment_mapping_refcnt(iop);
     371  }
    335372
    336373  rtems_chain_append( &mmap_mappings, &mapping->node );
  • cpukit/posix/src/munmap.c

    re19da87 rc6bb1c33  
    4747  }
    4848
     49  /* Check for illegal addresses. Watch out for address wrap. */
     50  if (addr + len < addr) {
     51    errno = EINVAL;
     52    return -1;
     53  }
     54
    4955  /*
    5056   * Obtain the mmap lock. Sets errno on failure.
     
    6470        shm_munmap(mapping->iop);
    6571      }
    66       refcnt = rtems_libio_decrement_mapping_refcnt(mapping->iop);
    67       if ( refcnt == 0 ) {
    68         rtems_libio_check_deferred_free(mapping->iop);
     72      if ( mapping->iop != NULL ) {
     73        refcnt = rtems_libio_decrement_mapping_refcnt(mapping->iop);
     74        if ( refcnt == 0 ) {
     75          rtems_libio_check_deferred_free(mapping->iop);
     76        }
    6977      }
    7078      /* only free the mapping address for non-fixed mapping */
  • cpukit/posix/src/shmopen.c

    re19da87 rc6bb1c33  
    104104    rtems_set_errno_and_return_minus_one( err );
    105105  }
     106  return 0;
     107}
     108
     109static int shm_mmap(
     110  rtems_libio_t *iop,
     111  void** addr,
     112  size_t len,
     113  int prot,
     114  off_t off
     115)
     116{
     117  POSIX_Shm_Control *shm = iop_to_shm( iop );
     118
     119  _Objects_Allocator_lock();
     120
     121  *addr = (*shm->shm_object.ops->object_mmap)( &shm->shm_object, len, prot, off);
     122  if ( *addr != NULL ) {
     123    /* Keep a reference in the shared memory to prevent its removal. */
     124    ++shm->reference_count;
     125
     126    /* Update atime */
     127    _POSIX_Shm_Update_atime(shm);
     128  } else {
     129    _Objects_Allocator_unlock();
     130    rtems_set_errno_and_return_minus_one( ENOMEM );
     131  }
     132
     133  _Objects_Allocator_unlock();
     134
    106135  return 0;
    107136}
     
    276305  .fcntl_h = rtems_filesystem_default_fcntl,
    277306  .kqfilter_h = rtems_filesystem_default_kqfilter,
     307  .mmap_h = shm_mmap,
    278308  .poll_h = rtems_filesystem_default_poll,
    279309  .readv_h = rtems_filesystem_default_readv,
Note: See TracChangeset for help on using the changeset viewer.