1 /* In OpenBSD, if you write to a file, another process doesn't see it
2  * in its mmap.  Returns with exit status 0 if that is the case, 1 if
3  * it's coherent, and other if there's a problem. */
4 #include <err.h>
5 #include <sys/mman.h>
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <errno.h>
13 
14 #define DATA "coherent.mmap"
15 
main(int argc,char * argv[])16 int main(int argc, char *argv[])
17 {
18 	int tochild[2], toparent[2];
19 	int fd;
20 	volatile unsigned char *map;
21 	unsigned char *page;
22         const char *fname = argv[1];
23 	char c = 0;
24 
25 	if (pipe(tochild) != 0 || pipe(toparent) != 0)
26 		err(2, "Creating pipe");
27 
28 	if (!fname)
29 		fname = DATA;
30 
31 	fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0600);
32 	if (fd < 0)
33 		err(2, "opening %s", fname);
34 	unlink(fname);
35 
36 	switch (fork()) {
37 	case -1:
38 		err(2, "Fork");
39 	case 0:
40 		close(tochild[1]);
41 		close(toparent[0]);
42 
43 		/* Wait for parent to create file. */
44 		if (read(tochild[0], &c, 1) != 1)
45 			err(2, "reading from parent");
46 
47 		/* Alter first byte. */
48 		pwrite(fd, &c, 1, 0);
49 
50 		if (write(toparent[1], &c, 1) != 1)
51 			err(2, "writing to parent");
52 		exit(0);
53 
54 	default:
55 		close(tochild[0]);
56 		close(toparent[1]);
57 
58 		/* Create a file and mmap it. */
59 		page = malloc(getpagesize());
60 		memset(page, 0x42, getpagesize());
61 		if (write(fd, page, getpagesize()) != getpagesize())
62 			err(2, "writing first page");
63 		map = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE,
64 			   MAP_SHARED, fd, 0);
65 		if (map == MAP_FAILED)
66 			err(2, "mapping file");
67 
68 		if (*map != 0x42)
69 			errx(2, "first byte isn't 0x42!");
70 
71 		/* Tell child to alter file. */
72 		if (write(tochild[1], &c, 1) != 1)
73 			err(2, "writing to child");
74 
75 		if (read(toparent[0], &c, 1) != 1)
76 			err(2, "reading from child");
77 
78 		if (*map)
79 			errx(0, "mmap incoherent: first byte isn't 0.");
80 
81 		exit(1);
82 	}
83 }
84