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