1*bc1257b2Sphessler /* $OpenBSD: mmap_mod.c,v 1.2 2010/06/20 17:56:07 phessler Exp $ */
297ceb7c9Sart
397ceb7c9Sart /*
497ceb7c9Sart * Public domain. 2007, Artur Grabowski <art@openbsd.org>
597ceb7c9Sart */
697ceb7c9Sart
797ceb7c9Sart #include <sys/types.h>
897ceb7c9Sart #include <sys/mman.h>
997ceb7c9Sart #include <err.h>
1097ceb7c9Sart #include <stdlib.h>
1197ceb7c9Sart #include <stdio.h>
12*bc1257b2Sphessler #include <string.h>
1397ceb7c9Sart #include <unistd.h>
1497ceb7c9Sart
1597ceb7c9Sart /*
1697ceb7c9Sart * Test a corner case where a pmap can lose mod/ref bits after unmapping
1797ceb7c9Sart * and remapping a page.
1897ceb7c9Sart */
1997ceb7c9Sart int
main()2097ceb7c9Sart main()
2197ceb7c9Sart {
2297ceb7c9Sart char name[20] = "/tmp/fluff.XXXXXX";
2397ceb7c9Sart char *buf, *pat;
2497ceb7c9Sart size_t ps;
2597ceb7c9Sart int fd;
2697ceb7c9Sart
2797ceb7c9Sart ps = getpagesize();
2897ceb7c9Sart
2997ceb7c9Sart if ((fd = mkstemp(name)) == -1)
3097ceb7c9Sart err(1, "mkstemp");
3197ceb7c9Sart
3297ceb7c9Sart if (unlink(name) == -1)
3397ceb7c9Sart err(1, "unlink");
3497ceb7c9Sart
3597ceb7c9Sart if (ftruncate(fd, ps))
3697ceb7c9Sart err(1, "ftruncate");
3797ceb7c9Sart
3897ceb7c9Sart if ((pat = malloc(ps)) == NULL)
3997ceb7c9Sart err(1, "malloc");
4097ceb7c9Sart
4197ceb7c9Sart memset(pat, 'a', ps);
4297ceb7c9Sart
4397ceb7c9Sart if (pwrite(fd, pat, ps, 0) != ps)
4497ceb7c9Sart err(1, "write");
4597ceb7c9Sart
4697ceb7c9Sart buf = mmap(NULL, ps, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);
4797ceb7c9Sart if (buf == MAP_FAILED)
4897ceb7c9Sart err(1, "mmap");
4997ceb7c9Sart
5097ceb7c9Sart if (*buf != 'a')
5197ceb7c9Sart errx(1, "mapped area - no file data ('%c' != 'a')", *buf);
5297ceb7c9Sart
5397ceb7c9Sart memset(buf, 'x', ps);
5497ceb7c9Sart
5597ceb7c9Sart if (munmap(buf, ps) == -1)
5697ceb7c9Sart err(1, "munmap");
5797ceb7c9Sart
5897ceb7c9Sart buf = mmap(NULL, ps, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);
5997ceb7c9Sart if (buf == MAP_FAILED)
6097ceb7c9Sart err(1, "mmap 2");
6197ceb7c9Sart
6297ceb7c9Sart if (*buf != 'x')
6397ceb7c9Sart errx(1, "mapped area lost modifications ('%c' != 'x')", *buf);
6497ceb7c9Sart
6597ceb7c9Sart if (msync(buf, ps, MS_SYNC) == -1)
6697ceb7c9Sart err(1, "msync");
6797ceb7c9Sart
6897ceb7c9Sart if (pread(fd, pat, ps, 0) != ps)
6997ceb7c9Sart err(1, "pread");
7097ceb7c9Sart
7197ceb7c9Sart if (*pat != 'x')
7297ceb7c9Sart errx(1, "synced area lost modifications ('%c' != 'x')", *pat);
7397ceb7c9Sart
7497ceb7c9Sart return (0);
7597ceb7c9Sart }
76