ptg10805159
Section 14.8 Memory-Mapped I/O 527
references to the mapped region then reference the copy.(One use
of this flag is for a debugger that maps the text portion of a
program file but allows the user to modify the instructions. Any
modifications affect the copy,not the original program file.)
Each implementation has additionalMAP_xxxflag values, which arespecific to that
implementation. Check themmap( 2 )manual page on your system for details.
The value ofoffand the value ofaddr(ifMAP_FIXEDis specified) areusually
required to be multiples of the system’s virtual memory page size. This value can be
obtained from the sysconf function (Section 2.5.4) with an argument of
_SC_PAGESIZEor_SC_PAGE_SIZE.Sinceoffandaddrareoften specified as 0, this
requirement is not a big deal.
This requirement is usually imposed by the system implementations. Although the Single
UNIX Specification no longer requires that this condition be satisfied, all the platforms covered
in this book, except FreeBSD 8.0, have this requirement. FreeBSD 8.0 allows us to use any
address alignment and offset alignment as long as the alignments match.
Since the starting offset of the mapped file is tied to the system’s virtual memory
page size, what happens if the length of the mapped region isn’t a multiple of the page
size? Assume that the file size is 12 bytes and that the system’s page size is 512 bytes.
In this case, the system normally provides a mapped region of 512 bytes, and the final
500 bytes of this region areset to 0.We can modify the final 500 bytes, but any changes
we make to them arenot reflected in the file. Thus we cannot append to a file with
mmap.Wemust first grow the file, as we will see in Figure14.27.
Twosignals arenormally used with mapped regions.SIGSEGVis normally used to
indicate that we have tried to access memory that is not available to us. This signal can
also be generated if we try to storeinto a mapped region that we specified tommapas
read-only.TheSIGBUSsignal can be generated if we access a portion of the mapped
region that does not make sense at the time of the access. For example, assume that we
map a file using the file’s size, but before we reference the mapped region, the file’s size
is truncated by some other process. If we then try to access the memory-mapped region
corresponding to the end portion of the file that was truncated, we’ll receiveSIGBUS.
Amemory-mapped region is inherited by a child across afork(since it’s part of
the parent’s address space), but for the same reason, is not inherited by the new
program across anexec.
We can change the permissions on an existing mapping by callingmprotect.
#include <sys/mman.h>
int mprotect(void *addr,size_tlen,int prot);
Returns: 0 if OK,−1 on error
The legal values forprotarethe same as those formmap(Figure14.25). Be awarethat
implementations may requirethe address argument to be an integral multiple of the
system’s page size.
When we modify pages that we’ve mapped into our address space using the
MAP_SHAREDflag, the changes aren’t written back to the file immediately.Instead, the