mmap() — Map pages of memory
Standards
| Standards / Extensions | C or C++ | Dependencies |
|---|---|---|
XPG4.2
Single UNIX Specification, Version 3 z/OS® UNIX |
both |
Format
#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/mman.h>
void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);General description
The mmap() function establishes a mapping between an address space of a process
(for len bytes) and a file that is associated with the file descriptor
fildes at offset off for
len bytes. The format of the call is as follows:
pa=mmap(addr, len, prot, flags, fildes, off); The value of pa is an unspecified function of the argument
addr and values of flags, further described
below. A successful mmap() call returns pa as its
results. The address ranges covered by [pa, pa +
len] and [off, off +
len] must be legitimate for the possible (not necessarily current) address
space of a process and the file, respectively.
If the size of the mapped file changes after the call to mmap(), the effect of
references to portions of the mapped region that correspond to added or removed portions of the file
is unspecified.
<sys/mman.h>: - PROT_READ
- Page can be read.
- PROT_WRITE
- Page can be written.
- PROT_EXEC
- Page can be executed.
- PROT_NONE
- Page cannot be accessed.
Implementations need not enforce all combinations of access permissions. However, write are permitted only when PROT_WRITE has been set.
sys/mman.h>: - MAP_SHARED
- Share changes.
- MAP_PRIVATE
- Changes are private.
- MAP_FIXED
- Interpret
addrexactly. - __MAP_MEGA
- Map in megabyte increments.
- __MAP_64
- Map storage above the 2-gigabyte addressing range.
MAP_ANONYMOUS
The mapping is not backed by any file and the memory contents are initialized to zero. When
MAP_ANONYMOUS is set, the fildesargument must be -1 and theoffargument must be zero. MAP_ANONYMOUS can be used with any of the other Map_type options.
MAP_ANON 
Synonym for MAP_ANONYMOUS.
The MAP_PRIVATE and MAP_SHARED flags control the visibility of write references to the memory region. Exactly one of these flags must be specified. The mapping type is retained across a fork.
If MAP_SHARED is set in flags, write references to the memory region by the calling process might change the file and are visible in all MAP_SHARED mappings of the same portion of the file by any process.
If MAP_PRIVATE is set in flags, write references to the memory region by the calling process do not change the file and are not visible to any process in other mappings of the same portion of the file.
All changes to the mapped data made by processes that have mapped the memory region using MAP_SHARED are shared and are visible to all other processes that have mapped the same file-offset range.
When MAP_FIXED is set in the flags argument, the implementation is
informed that the value of pa must be addr,
exactly. If MAP_FIXED is set, mmap() might return (void*)-1 and
set errno to EINVAL. If a MAP_FIXED request is successful, the mapping that is
established that is by mmap() replaces any previous mappings for the process's
pages in the range [pa, pa + len].
When MAP_FIXED is not set, the implementation uses addr in an unspecified manner to arrive to pa. The pa so chosen will be an area of the address space, which the implementation deems suitable for a mapping of len bytes to the file. All implementation interprets an addr value of 0 as granting the implementation complete freedom in selecting pa, subject to constraints described below. A nonzero value of addr is taken to be a suggestion of a process address near which the mapping should be placed. When the implementation selects a value for pa, it never places a mapping at address 0, nor does it replace any extant mapping, nor map into dynamic memory allocation areas.
The off argument is constrained to be aligned and sized according to
the value returned by sysconf() when passed_SC_PAGESIZE or_SC_PAGE_SIZE. When
MAP_FIXED is specified, the argument addr must also meet these
constraints. The implementation performs mapping operations over whole pages. Thus, while the
argument len need not meet a size or alignment constraint, the
implementation includes, in any mapping operation, any partial page specified by the range
[pa, pa + len].
The implementation always zero-fills any partial page at the end of a memory region. Further,
the implementation never writes out any modified portions of the last page of a file that are beyond
the end of the mapped portion of the file. If the mapping established by mmap()
extends into pages beyond the page containing the last byte of the file, an application references
to any of the pages in the mapping that are beyond the last page results in the delivery of a SIGBUS
or SIGSEGV signal.
The mmap() function adds an extra reference to the file associated with the
file descriptor fildes is not removed by a subsequent close() on that file
descriptor. This reference is removed when there are not more mappings to the file.
The st_atime field of the mapped file might be marked for update at any time between the
mmap() call and the corresponding munmap() call. The initial read
or write reference to a mapped region causes the file's set_atime field to be marked for update if
it has not already been marked for update.
The st_ctime and st_mtime fields of a file that is mapped with
MAP_SHARED and PROT_WRITE, will be marked for update at stime point in the interval
between a write reference to the mapped region and the next call to msync() with
MS_ASYNC or MS_SYNC for that portion of the file by any process. If there is no such call, these
fields might be marked for update at any time after a write reference if the underlying file is
modified as a result.
If a memory-mapped region is not unmapped before the process terminates, process termination
will not automatically write out to disk any modified data in the mapped region. Modified private
data in a MAP_PRIVATE region will be discarded. If the map region is MAP_SHARED, the modified data
continue to reside in the cache (if the same file-offset range is being shared) and might ultimately
be written out to disk by another process that uses the msync() service. However,
if no other processes map the same file-offset range as MAP_SHARED, the modified data is
discarded.
There might be implementation-dependent limits on the number of memory regions that can be
mapped (per process or per system). If such a limit is imposed, whether the number of memory regions
that can be mapped by a process is decreased by the use of shmat() is
implementation-dependent.
Specification of the __MAP_MEGA option results in the system allocating storage to map the file
in megabyte increments. This option should only be used for large files. Any file over half a
megabyte in size will likely achieve better performance by using this option. When using this
option, mmaps and munmaps are in megabyte ranges on megabyte
boundaries.
When __MAP_MEGA is specified, all changes to the mapped data are shared. Modifications to the
mapped data are visible to all other processes that map the same file-offset range. That is,
__MAP_MEGA behaves much like MAP_SHARED. __MAP_MEGA is mutually exclusive with MAP_PRIVATE and
MAP_SHARED. Specification of __MAP_MEGA with either MAP_PRIVATE or MAP_SHARED will result in the
request failing with errno set to EINVAL.
The __MAP_MEGA option might be specified with MAP_FIXED.
Map_address parameter: If the map address is not zero and __MAP_MEGA has been specified,
then for non MAP_FIXED requests, the kernel attempts to create the mapping at the map_address,
truncated to the nearest megabyte boundary. If unsuccessful, it proceeds as if a map_address of zero
were specified. For MAP_FIXED requests, the value of map_address must be multiples of the segment
size (megabyte multiples). If not, the mmap request fails with
errno set to EINVAL.
Map_length parameter: When __MAP_MEGA is specified, mapping operations are performed over whole segments (megabyte chunks). If the length is not a multiple of the segment size, the entire trailing portion of the last segment will also be mapped into the user storage.
File_descriptor: The file descriptor identifies the file being mapped. If an attempt is
made to map a file that is already mapped but was mapped with a different specification of
__MAP_MEGA, then the current request fails with errno set to
EINVAL-MMapTypeMismatch. That is, at any point in time a file might be mapped with the __MAP_MEGA
option or without the __MAP_MEGA option but not both ways at the same time.
For a __MAP_MEGA mapping, if this is the first map to the file represented by the specified file
descriptor then whether the file was opened for read or for write will determine what protection
options might be specified for the file by this mmap and any future
mmaps and mprotects, by this or any other process mapping to the
same file. If the file was opened for read but not write, then only PROT_READ, PROT_EXEC or
PROT_NONE are allowed. If the file was opened for write, then any of the protection options will be
allowed. Only regular files might be mapped. Note also that remote files accessed through NFS or DFS
might not be mapped.
Protect_options: The specification that is made for Protect_options has a global effect when the file is mapped with the __MAP_MEGA option. The Protect_option specified immediately effects all processes currently mapped to the same file-offset range.
Large file support for z/OS UNIX files: Large z/OS UNIX files are supported automatically for AMODE 64 C/C++ applications. AMODE 31 C/C++ applications must be compiled with the long long data type support enabled and define the _LARGE_FILES feature test macro before any headers are included to enable this function to operate on z/OS UNIX files that are larger than 2 GB in size. File size and offset fields are enlarged to 63 bits in width. Therefore, any other function operating on the file is required to define the _LARGE_FILES feature test macro as well.
- Set the
flagsargument to __MAP_64. - Set the
addrargument to the value above 64G. - Set the
lenargument to the value greater than 2G.
Usage notes
- The
mmap()function does not support shared memory objects or typed memory objects. - When __MAP_64 is specified, the
addrargument must be either 0 or a value greater than 64G; otherwise, an EINVAL error is returned. - When __MAP_64 is specified, it might be combined with MAP_FIXED or MAP_SHARED or both.
- When both __MAP_64 and MAP_FIXED are specified, the first fullword of the
addrargument must benonzero; otherwise, an EINVAL error is returned. - For non-MAP_FIXED requests, if
addrspecifies an address that is above 64G, the system attempts to create a mapping at the address that is specified byaddrand the address must be on a segment boundary. If it is unsuccessful, it proceeds as if anaddrvalue of zero were specified, but will attempt to create a mapping above 64G.
When MAP_ANONYMOUS or MAP_ANON is specified, the
fildesparameter must be -1 and theoffparameter must be 0.
Returned value
If successful, mmap() returns the address at which the mapping was placed.
errno to
one of the following values: - Error Code
- Description
- EACCES
- The fildes argument is not open for read, regardless of the protection that is specified , or fildes is not open for write and PROT_WRITE was specified for a MAP_SHARED type mapping.
- EBADF
- The fildes argument is not a valid open file descriptor.
- EINVAL
- The addr argument (if MAP_FIXED was specified) or
off is not a multiple of the page size as returned by
sysconf(), or are considered invalid by the implementation.The value of flags is invalid (neither MAP_PRIVATE nor MAP_SHARED is set).
- EMFILE
- The number of mapped regions would exceed an implementation-dependent limit (per process or per system).
- ENODEV
- The fildes argument refers to a file whose type is not supported by
mmap(). - ENOMEM
- MAP_FIXED was specified, and the range [addr, addr + range [addr, addr + len], rounding len] exceeds that allowed for the address space for a process; or if MAP_FIXED was not specified and there is insufficient room in the address space to effect the mapping.
- ENXIO
- Address in the range [off, off + len] are invalid for fildes
- EOVERFLOW
- The file is a regular file and the value of off plus
lenexceeds the offset maximum that is established in the open file.Note: Starting with z/OS V1.9, environment variable _EDC_EOVERFLOW can be used to control behavior ofmmap()about detecting an EOVERFLOW condition for z/OS UNIX files. By default,mmap()will not set EOVERFLOW when the offset maximum is exceeded associated withfildes. When _EDC_EOVERFLOW is set to YES, mmap() checks for an overflow condition.
Related information
- sys/mman.h — Memory management
- exec functions
- fcntl() — Control open file descriptors
- fork() — Create a new process
- lockf() — Record locking on files
- mprotect() — Set protection of memory mapping
- msync() — Synchronize memory with physical storage
- munmap() — Unmap pages of memory
- shmat() — Shared memory attach operation
- sysconf() — Determine system configuration options