#include #include #include #include #include #include #include static void cow(void) { pid_t child; child = fork(); switch (child) { case -1: /* error */ err(1, "fork"); case 0: /* child */ _Exit(0); default: /* parent */ if (waitpid(child, NULL, 0) == -1) err(1, "waitpid"); } } int main(void) { const size_t PAGE_SIZE = sysconf(_SC_PAGESIZE); void *p, *q; p = mmap(/*hint*/NULL, /*size*/PAGE_SIZE, PROT_MPROTECT(PROT_READ|PROT_WRITE), MAP_ANON|MAP_PRIVATE, /*fd*/-1, /*offset*/0); if (p == MAP_FAILED) err(1, "mmap"); q = mremap(/*oldp*/p, PAGE_SIZE, /*newp*/NULL, PAGE_SIZE, MAP_REMAPDUP); if (q == MAP_FAILED) err(1, "mmap"); if (mprotect(p, PAGE_SIZE, PROT_WRITE) == -1) err(1, "mprotect w"); if (mprotect(q, PAGE_SIZE, PROT_READ) == -1) err(1, "mprotect r"); assert(*((const char *)q) == 0); *((char *)p) = 1; assert(*((const char *)q) == 1); cow(); assert(*((const char *)q) == 1); *((char *)p) = 2; assert(*((const char *)q) == 2); return 0; }