1501Ssundar#include <stdio.h>
2501Ssundar#include <string.h>
3501Ssundar#include <sys/stat.h>
4877Sattila#include <unistd.h>
5501Ssundar
6501Ssundar#include <OS.h>
7501Ssundar
8877Sattilaconst char* kInitialValue = "/dev/null";
9501Ssundarconst char* kChangedValue = "Argh!";
10501Ssundar
11501Ssundarint
12501Ssundarmain(int argc, const char* const* argv)
13501Ssundar{
14877Sattila	thread_id parent = find_thread(NULL);
15501Ssundar
16501Ssundar	char* globalVar = NULL;
17501Ssundar	area_id area = create_area("cow test", (void**)&globalVar,
18877Sattila		B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
19501Ssundar	if (area < 0) {
20501Ssundar		printf("failed to create area\n");
21501Ssundar		return 1;
22501Ssundar	}
23501Ssundar
24501Ssundar	strcpy(globalVar, kInitialValue);
25501Ssundar
26501Ssundar	printf("[%ld] parent: before fork(): globalVar(%p): \"%s\"\n", parent,
27501Ssundar		globalVar, globalVar);
28501Ssundar
29501Ssundar	pid_t child = fork();
30501Ssundar	if (child == 0) {
31501Ssundar		// child
32501Ssundar		child = find_thread(NULL);
33501Ssundar
34501Ssundar		// let the kernel read access the page
35501Ssundar		struct stat st;
36501Ssundar		stat(globalVar, &st);
37501Ssundar
38501Ssundar		printf("[%ld] child: after kernel read: globalVar: \"%s\"\n",
39501Ssundar			child, globalVar);
40501Ssundar
41501Ssundar		// write access the page from userland
42501Ssundar		strcpy(globalVar, kChangedValue);
43501Ssundar
44501Ssundar		printf("[%ld] child: after change: globalVar: \"%s\"\n", child,
45501Ssundar			globalVar);
46501Ssundar
47501Ssundar	} else {
48501Ssundar		// parent
49501Ssundar
50501Ssundar		// wait for the child
51589Ssundar		status_t exitVal;
52501Ssundar		while (wait_for_thread(child, &exitVal) == B_INTERRUPTED);
53501Ssundar
54501Ssundar		// check the value
55501Ssundar		printf("[%ld] parent: after exit child: globalVar: \"%s\"\n",
56501Ssundar			parent, globalVar);
57501Ssundar
58501Ssundar		if (strcmp(globalVar, kInitialValue) == 0)
59501Ssundar			printf("test OK\n");
60501Ssundar		else
61501Ssundar			printf("test FAILED: child process changed parent's memory!\n");
62501Ssundar	}
63501Ssundar
64501Ssundar	return 0;
65501Ssundar}
66501Ssundar