1. 코드 분석
1. tlpi-dist/mmap/mmcat.c
1. 코드
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "tlpi_hdr.h"
int
main(int argc, char *argv[])
{
char *addr;
int fd;
struct stat sb;
if (argc != 2 || strcmp(argv[1], "--help") == 0)
usageErr("%s file\n", argv[0]);
fd = open(argv[1], O_RDONLY);
if (fd == -1)
errExit("open");
if (fstat(fd, &sb) == -1)
errExit("fstat");
if (sb.st_size == 0)
exit(EXIT_SUCCESS);
addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED)
errExit("mmap");
if (write(STDOUT_FILENO, addr, sb.st_size) != sb.st_size)
fatal("partial/failed write");
exit(EXIT_SUCCESS);
}
2. 동작 모습

3. 디버깅 및 분석
2. tlpi-dist/mmap/t_mmap.c
1. 코드
#include <sys/mman.h>
#include <fcntl.h>
#include "tlpi_hdr.h"
#define MEM_SIZE 10
int
main(int argc, char *argv[])
{
char *addr;
int fd;
if (argc < 2 || strcmp(argv[1], "--help") == 0)
usageErr("%s file [new-value]\n", argv[0]);
fd = open(argv[1], O_RDWR);
if (fd == -1)
errExit("open");
addr = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED)
errExit("mmap");
if (close(fd) == -1)
errExit("close");
printf("Current string=%.*s\n", MEM_SIZE, addr);
if (argc > 2) {
if (strlen(argv[2]) >= MEM_SIZE)
cmdLineErr("'new-value' too large\n");
memset(addr, 0, MEM_SIZE);
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);
}
2. 동작 모습

3. 디버깅 및 분석
3. tlpi-dist/vmem/t_mprotect.c
1. 코드
#define _BSD_SOURCE
#include <sys/mman.h>
#include "tlpi_hdr.h"
#define LEN (1024 * 1024)
#define SHELL_FMT "cat /proc/%ld/maps | grep zero"
#define CMD_SIZE (sizeof(SHELL_FMT) + 20)
int
main(int argc, char *argv[])
{
char cmd[CMD_SIZE];
char *addr;
addr = mmap(NULL, LEN, PROT_NONE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED)
errExit("mmap");
printf("Before mprotect()\n");
snprintf(cmd, CMD_SIZE, SHELL_FMT, (long) getpid());
system(cmd);
if (mprotect(addr, LEN, PROT_READ | PROT_WRITE) == -1)
errExit("mprotect");
printf("After mprotect()\n");
system(cmd);
exit(EXIT_SUCCESS);
}
2. 동작 모습

3. 디버깅 및 분석
4. tlpi-dist/vmem/memlock.c
1. 코드
#define _BSD_SOURCE
#include <sys/mman.h>
#include "tlpi_hdr.h"
static void
displayMincore(char *addr, size_t length)
{
unsigned char *vec;
long pageSize, numPages, j;
#ifndef _SC_PAGESIZE
pageSize = getpagesize();
#else
pageSize = sysconf(_SC_PAGESIZE);
#endif
numPages = (length + pageSize - 1) / pageSize;
vec = malloc(numPages);
if (vec == NULL)
errExit("malloc");
if (mincore(addr, length, vec) == -1)
errExit("mincore");
for (j = 0; j < numPages; j++) {
if (j % 64 == 0)
printf("%s%10p: ", (j == 0) ? "" : "\n", addr + (j * pageSize));
printf("%c", (vec[j] & 1) ? '*' : '.');
}
printf("\n");
free(vec);
}
int
main(int argc, char *argv[])
{
char *addr;
size_t len, lockLen;
long pageSize, stepSize, j;
if (argc != 4 || strcmp(argv[1], "--help") == 0)
usageErr("%s num-pages lock-page-step lock-page-len\n", argv[0]);
#ifndef _SC_PAGESIZE
pageSize = getpagesize();
if (pageSize == -1)
errExit("getpagesize");
#else
pageSize = sysconf(_SC_PAGESIZE);
if (pageSize == -1)
errExit("sysconf(_SC_PAGESIZE)");
#endif
len = getInt(argv[1], GN_GT_0, "num-pages") * pageSize;
stepSize = getInt(argv[2], GN_GT_0, "lock-page-step") * pageSize;
lockLen = getInt(argv[3], GN_GT_0, "lock-page-len") * pageSize;
addr = mmap(NULL, len, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED)
errExit("mmap");
printf("Allocated %ld (%#lx) bytes starting at %p\n",
(long) len, (unsigned long) len, addr);
printf("Before mlock:\n");
displayMincore(addr, len);
for (j = 0; j + lockLen <= len; j += stepSize)
if (mlock(addr + j, lockLen) == -1)
errExit("mlock");
printf("After mlock:\n");
displayMincore(addr, len);
exit(EXIT_SUCCESS);
}
2. 동작 모습

3. 디버깅 및 분석