1#include <stdio.h>
2#include <string.h>
3#include <sys/stat.h>
4#include <unistd.h>
5
6#include <OS.h>
7
8const char* kInitialValue = "/dev/null";
9const char* kChangedValue = "Argh!";
10
11int
12main(int argc, const char* const* argv)
13{
14	thread_id parent = find_thread(NULL);
15
16	char* globalVar = NULL;
17	area_id area = create_area("cow test", (void**)&globalVar,
18		B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
19	if (area < 0) {
20		printf("failed to create area\n");
21		return 1;
22	}
23
24	strcpy(globalVar, kInitialValue);
25
26	printf("[%ld] parent: before fork(): globalVar(%p): \"%s\"\n", parent,
27		globalVar, globalVar);
28
29	pid_t child = fork();
30	if (child == 0) {
31		// child
32		child = find_thread(NULL);
33
34		// let the kernel read access the page
35		struct stat st;
36		stat(globalVar, &st);
37
38		printf("[%ld] child: after kernel read: globalVar: \"%s\"\n",
39			child, globalVar);
40
41		// write access the page from userland
42		strcpy(globalVar, kChangedValue);
43
44		printf("[%ld] child: after change: globalVar: \"%s\"\n", child,
45			globalVar);
46
47	} else {
48		// parent
49
50		// wait for the child
51		status_t exitVal;
52		while (wait_for_thread(child, &exitVal) == B_INTERRUPTED);
53
54		// check the value
55		printf("[%ld] parent: after exit child: globalVar: \"%s\"\n",
56			parent, globalVar);
57
58		if (strcmp(globalVar, kInitialValue) == 0)
59			printf("test OK\n");
60		else
61			printf("test FAILED: child process changed parent's memory!\n");
62	}
63
64	return 0;
65}
66