Memory Mappings 1029
addr = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED)
errExit("mmap");
if (close(fd) == -1) /* No longer need 'fd' */
errExit("close");
printf("Current string=%.*s\n", MEM_SIZE, addr);
/* Secure practice: output at most MEM_SIZE bytes */
if (argc > 2) { /* Update contents of region */
if (strlen(argv[2]) >= MEM_SIZE)
cmdLineErr("'new-value' too large\n");
memset(addr, 0, MEM_SIZE); /* Zero out region */
strncpy(addr, argv[2], MEM_SIZE - 1);
if (msync(addr, MEM_SIZE, MS_SYNC) == -1)
errExit("msync");
printf("Copied \"%s\" to shared memory\n", argv[2]);
}
exit(EXIT_SUCCESS);
}
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– mmap/t_mmap.c
49.4.3 Boundary Cases
In many cases, the size of a mapping is a multiple of the system page size, and the
mapping falls entirely within the bounds of the mapped file. However, this is not
necessarily so, and we now look at what happens when these conditions don’t hold.
Figure 49-3 portrays the case where the mapping falls entirely within the
bounds of the mapped file, but the size of the region is not a multiple of the system
page size (which we assume is 4096 bytes for the purposes of this discussion).
Figure 49-3: Memory mapping whose length is not a multiple of the system page size
Memory
region
references
yield SIGSEGV
Mapped file
(9500 bytes)
remainder
of page
file offset: 0
byte offset: 0 6000
mmap(0, 6000, prot, MAP_SHARED, fd, 0);
accessible, mapped to file
9499
5999 81918192
requested size of mapping
actual mapped region of file
81918192
unmapped