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