The Linux Programming Interface

(nextflipdebug5) #1
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
Free download pdf