1 /* $OpenBSD: mmap_mod.c,v 1.2 2010/06/20 17:56:07 phessler Exp $ */ 2 3 /* 4 * Public domain. 2007, Artur Grabowski <art@openbsd.org> 5 */ 6 7 #include <sys/types.h> 8 #include <sys/mman.h> 9 #include <err.h> 10 #include <stdlib.h> 11 #include <stdio.h> 12 #include <string.h> 13 #include <unistd.h> 14 15 /* 16 * Test a corner case where a pmap can lose mod/ref bits after unmapping 17 * and remapping a page. 18 */ 19 int 20 main() 21 { 22 char name[20] = "/tmp/fluff.XXXXXX"; 23 char *buf, *pat; 24 size_t ps; 25 int fd; 26 27 ps = getpagesize(); 28 29 if ((fd = mkstemp(name)) == -1) 30 err(1, "mkstemp"); 31 32 if (unlink(name) == -1) 33 err(1, "unlink"); 34 35 if (ftruncate(fd, ps)) 36 err(1, "ftruncate"); 37 38 if ((pat = malloc(ps)) == NULL) 39 err(1, "malloc"); 40 41 memset(pat, 'a', ps); 42 43 if (pwrite(fd, pat, ps, 0) != ps) 44 err(1, "write"); 45 46 buf = mmap(NULL, ps, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0); 47 if (buf == MAP_FAILED) 48 err(1, "mmap"); 49 50 if (*buf != 'a') 51 errx(1, "mapped area - no file data ('%c' != 'a')", *buf); 52 53 memset(buf, 'x', ps); 54 55 if (munmap(buf, ps) == -1) 56 err(1, "munmap"); 57 58 buf = mmap(NULL, ps, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0); 59 if (buf == MAP_FAILED) 60 err(1, "mmap 2"); 61 62 if (*buf != 'x') 63 errx(1, "mapped area lost modifications ('%c' != 'x')", *buf); 64 65 if (msync(buf, ps, MS_SYNC) == -1) 66 err(1, "msync"); 67 68 if (pread(fd, pat, ps, 0) != ps) 69 err(1, "pread"); 70 71 if (*pat != 'x') 72 errx(1, "synced area lost modifications ('%c' != 'x')", *pat); 73 74 return (0); 75 } 76