xref: /openbsd/regress/sys/uvm/mmap_mod/mmap_mod.c (revision bc1257b2)
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
main()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