mmap(2)
NAME
mmap − map object into virtual memory
SYNOPSIS
#include <sys/mman.h>
caddr_t mmap(
caddr_t addr,
size_t len,
int prot,
int flags,
int fildes,
off_t off);
DESCRIPTION
mmap() creates a new memory mapped file or anonymous memory region. The format of the call is as follows:
pa = mmap( addr, len, prot, flags, fildes, off);
mmap() establishes a mapping between the process’s address space at an address pa for len bytes to an object represented by the file descriptor fildes at offset off for len bytes, or to an anonymous region of physical memory of size len bytes. A successful mmap() call returns pa as its result, where pa is an implementation-dependent function of the requested starting address and length for the new region, addr and len, as further described below.
If len is not a multiple of the page size returned by sysconf(_SC_PAGE_SIZE), then references are permitted to an address between pa+len and the next higher address that is an integer multiple of the page size; however, the results of any such references are undefined.
The flags argument specifies the attributes of the region. Values of the flags argument are constructed by bitwise-inclusive OR ing flags from the following list of symbolic names defined in <sys/mman.h>:
MAP_FILE Create a mapped file region.
MAP_ANONYMOUS Create an unnamed memory region.
MAP_VARIABLE Place region at implementation-computed address.
MAP_FIXED Place region at specified address.
MAP_SHARED Share changes between processes and underlying file object, if any.
MAP_PRIVATE Changes are private to a process.
The MAP_FILE and MAP_ANONYMOUS flags control whether the region to be mapped is a mapped file region or an anonymous shared memory region. Exactly one of these flags must be selected.
If MAP_FILE is set in flags:
• A new mapped file region is created, mapping the file associated with fildes.
• off specifies the file byte offset at which the mapping starts. This offset must be a multiple of the page size returned by sysconf(_SC_PAGE_SIZE).
• If the end of the mapped file region is beyond the end of the file, any reference to an address in the mapped file region corresponding to an offset beyond the end of the file results in the delivery of a SIGBUS signal to the process, unless the address lies in the last partial page corresponding to the range beyond the end of the file. The last partial page mapping the range beyond the end of the file is always initialized to zeros, and any modified portions of the last page of a file which are beyond its end are not written back to the file.
If MAP_ANONYMOUS is set in flags:
• A new memory region is created and initialized to all zeros. This memory region can be shared only with descendants of the current process.
• If the fildes argument is not −1, an EINVAL error is generated.
• The value of off is meaningless because there is no underlying file object for the memory region.
The MAP_VARIABLE and MAP_FIXED flags control the placement of the region as described below. Exactly one of these flags must be selected.
If MAP_VARIABLE is set in flags:
• If the requested address is NULL, or if it is not possible for the system to place the region at the requested address, the region is placed at an address selected by the system. If the requested address is not a multiple of the page size returned by sysconf(_SC_PAGE_SIZE), the system treats the address as if it were rounded up to the next larger page size multiple.
If MAP_FIXED is set in flags:
• If it is not possible for the system to place the region at the requested address, the mmap() function fails.
• addr must be a multiple of the page size returned by sysconf(_SC_PAGE_SIZE).
A region is never placed at an address where it would overlap with an existing region or a portion of the process address space that is already in use or reserved for other purposes. A region is always placed at a starting address that is an exact multiple of the page size returned by sysconf(_SC_PAGE_SIZE).
The MAP_PRIVATE and MAP_SHARED flags control the visibility of modifications to the mapped file or anonymous memory region. Exactly one of these flags must be selected.
If MAP_SHARED is set in flags:
• Modifications to the region are visible to other processes which have mapped the same file using MAP_SHARED.
• If the region is a mapped file region, modifications to the region are written to the underlying file.
If MAP_PRIVATE is set in flags:
• Modification to the mapped region by the calling process is not visible to other processes which have mapped the same region using either MAP_PRIVATE or MAP_SHARED. Modifications are not visible to descendant processes that have inherited the mapped region across a fork().
• If the region is a mapped file region, modifications to to the region are not written to the underlying file.
It is unspecified whether modifications by processes that have mapped a file using MAP_SHARED are visible to other processes that have mapped the same file using MAP_PRIVATE.
The prot argument specifies the mapped region’s access permissions. Header file <sys/mman.h> defines the following access permissions:
PROT_READ Region can be read
PROT_WRITE Region can be written
PROT_EXEC Region can be executed
PROT_NONE Region cannot be accessed
The prot argument can be PROT_NONE, or any combination of PROT_READ, PROT_WRITE , and PROT_EXEC OR -ed together. If PROT_NONE is not specified, the system may grant other access permissions to the region in addition to those explicitly requested, except that write access will not be granted unless PROT_WRITE is specified.
mmap() cannot create a mapped file region unless the file descriptor used to map the file is open for reading. For a mapped file region that is mapped with MAP_SHARED, mmap() grants write access permission only if the file descriptor is open for writing. If a region was mapped with either MAP_PRIVATE or MAP_ANONYMOUS, mmap() grants all requested access permissions.
After the successful completion of mmap(), fildes can be closed without effect on the mapped region or on the contents of the mapped file. Each mapped region creates a file reference, similar to an open file descriptor, that prevents the file data from being deallocated.
Whether modifications made to the file using write() are visible to mapped regions, and whether modification to a mapped region are visible with read(), is undefined except for the effect of msync().
If an enforcement-mode file lock is in effect for any range of a file, a call to mmap() to map any range of the file with access rights that would violate the lock fails. The msem_lock() and msem_unlock() semaphore interfaces can be used to coordinate shared access to a region created with the MAP_SHARED flag. The advisory locks of the lockf() or fcntl() interfaces have no effect on memory mapped access, but they can be used to coordinate shared access to a MAP_SHARED mapped file region.
For a memory mapped file, the st_atime and st_mtime values returned by stat() are updated when a page in the memory mapped region is read from or written to the file system.
After a call to fork(), the child process inherits all mapped regions with the same data and the same sharing and protection attributes as in the parent process. Each mapped file and anonymous memory region created with mmap() is unmapped upon process exit, and by a successful call to any of the exec functions.
A SIGBUS signal is delivered to a process when a write reference to a mapped file region would cause a file system error condition such as exceeding quota or file system space limits.
A SIGBUS signal is delivered to a process upon a write reference to a region without PROT_WRITE protection, or any reference to a region with PROT_NONE protection.
A call to mmap() with PROT_EXECUTE specified, but without PROT_WRITE specified for a MAP_SHARED|MAP_FILE mapping is treated by the system as the execution of the underlying file. This implies that such a call fails if the file is currently open for writing or mapped with MAP_SHARED|PROT_WRITE options by any process, and that if the call succeeds, the file cannot be opened for writing or subsequently mapped with MAP_SHARED|PROT_WRITE options as long as such mappings are present. A file’s status as an active executable file is determined only at the time of an exec(), exit(), or mmap() operation. mprotect() operations on a MAP_FILE|MAP_SHARED mapping have no effect on the underlying file’s status as an active executable file.
IMPLEMENTATION NOTES
Only regular files (not directories, named pipes, or device special files) can be mapped.
System swap resources are reserved for all mappings created with either MAP_PRIVATE or MAP_ANONYMOUS.
RETURN VALUE
Upon successful completion, mmap() returns the address at which the mapping was placed. Otherwise, mmap() returns −1 and sets errno to indicate the error.
ERRORS
mmap() fails if any of the following conditions are encountered:
[EACCESS] The file referred to by fildes is not open for read access, or the file is not open for write access and PROT_WRITE was set for a MAP_SHARED mapping operation, or PROT_EXECUTE was set for a MAP_SHARED mapping operation and the underlying file does not have execute permission.
[EBADF] fildes is not a valid file descriptor.
[EINVAL] flags or prot is invalid, or addr (with MAP_FIXED set) or off (with MAP_FILE set) is not a multiple of the page size returned by sysconf(_SC_PAGE_SIZE).
[ENODEV] fildes refers to an object that cannot be mapped, such as a terminal.
[ENOMEM] There is not enough address space to map len bytes, or MAP_FIXED was set and part of the address space range [addr, addr+len) (from, and including, addr to, but not including, addr+len) is not available for use.
[ENXIO] The addresses specified by the range [off, off+len) (from, and including, off to, but not including, off+len) are invalid for fildes.
[EAGAIN] The file represented by fildes has enforcement-mode file locking in effect for some range in the file. (see lockf(2), or fcntl(2)).
[ETXTBSY] MAP_SHARED and MAP_FILE are set, and PROT_EXECUTE is set and PROT_WRITE is not set, and the file being mapped is currently open for writing.
DEPENDENCIES
Series 700/800
Because the PA-RISC memory architecture utilizes a globally shared virtual address space between processes, and discourages multiple virtual address translations to the same physical address, all concurrently existing MAP_SHARED mappings of a file range must share the same virtual address offsets and hardware translations. PA-RISC -based HP-UX systems allocate virtual address ranges for shared memory and shared mapped files in the range 0x80000000 through 0xefffffff. This address range is used globally for all memory objects shared between processes.
This implies the following:
• Any single range of a file cannot be mapped multiply into different virtual address ranges.
• After the initial MAP_SHARED mmap() of a file range, all subsequent MAP_SHARED calls to mmap() to map the same range of a file must either specify MAP_VARIABLE in flags and inherit the virtual address range the system has chosen for this range, or specify MAP_FIXED with an addr that corresponds exactly to the address chosen by the system for the initial mapping. Only after all mappings for a file range have been destroyed can that range be mapped to a different virtual address.
• In most cases, two separate calls to mmap() cannot map overlapping ranges in a file. The virtual address range reserved for a file range is determined at the time of the initial mapping of the file range into a process address space. The system allocates only the virtual address range necessary to represent the initial mapping. As long as the initial mapping exists, subsequent attempts to map a different file range that includes any portion of the initial range may fail with an ENOMEM error if an extended contiguous address range that preserves the mappings of the initial range cannot be allocated.
• Separate calls to mmap() to map contiguous ranges of a file do not necessarily return contiguous virtual address ranges. The system may allocate virtual addresses for each call to mmap() on a first available basis.
• The use of MAP_FIXED is strongly discouraged because it is not portable. Using MAP_FIXED is generally unsuccessful on this implementation, and when it is successful, it may prevent the system from optimally allocating virtual address space.
The following combinations of protection modes are supported:
PROT_NONE
PROT_READ
PROT_READ|PROT_EXECUTE
PROT_READ|PROT_WRITE
PROT_READ|PROT_WRITE|PROT_EXECUTE
If a MAP_PRIVATE mapping is created of a file for which a MAP_SHARED mapping exists, a separate copy of a page for the MAP_PRIVATE mapping is created at the time of the first access to the page through the private mapping.
Series 300/400
The following combinations of protection modes are supported:
PROT_NONE
PROT_READ
PROT_READ|PROT_EXECUTE
PROT_READ|PROT_WRITE
PROT_READ|PROT_WRITE|PROT_EXECUTE
In addition, for protection modes that do not explicitly have PROT_EXECUTE set, individual pages within the region can be promoted to include PROT_EXECUTE permissions simply by executing code located within the region.
If a MAP_PRIVATE mapping is created of a file for which a MAP_SHARED mapping exists, a separate copy of a page for the MAP_PRIVATE mapping is created at the time of the first write reference to the page through the private mapping.
HP Clustered Environment
In a clustered environment, modifications to a MAP_SHARED mapped file region on one cluster node may not be visible to other processes on other cluster nodes that have the same file mapped with the MAP_SHARED option.
AUTHOR
mmap() was developed by HP, AT&T, and OSF.
SEE ALSO
fcntl(2), fork(2), ftruncate(2), lockf(2), madvise(2), mprotect(2), msem_init(2), msem_lock(2), msem_unlock(2), msync(2), munmap(2), sysconf(2), mman(5), stat(5).
STANDARDS CONFORMANCE
mmap(): AES [Series 300/400/700 only]
Hewlett-Packard Company — HP-UX Release 9.0: August 1992