xref: /haiku/src/tests/system/kernel/fibo_fork.cpp (revision f9e49fed7165de13e7fc375aa47c4ad07104e992)
1 /*
2  * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Copyright 2002, Manuel J. Petit. All rights reserved.
6  * Distributed under the terms of the NewOS License.
7  */
8 
9 
10 #include <image.h>
11 
12 #include <errno.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <unistd.h>
17 
18 
19 int gForked = 0;
20 
21 
22 static void
23 usage(char const *app)
24 {
25 	printf("usage: %s ###\n", app);
26 	exit(-1);
27 }
28 
29 
30 int
31 main(int argc, char *argv[])
32 {
33 	int result = 0;
34 
35 	if (argc != 2)
36 		usage(argv[0]);
37 
38 	int num = atoi(argv[1]);
39 
40 	if (num < 2) {
41 		result = num;
42 	} else {
43 		pid_t childA = fork();
44 		if (childA == 0) {
45 			// we're the child
46 			char buffer[64];
47 			char* args[]= { argv[0], buffer, NULL };
48 			int argCount = 2;
49 			gForked++;
50 
51 			snprintf(buffer, sizeof(buffer), "%d", num - 1);
52 			return main(argCount, args);
53 		} else if (childA < 0) {
54 			fprintf(stderr, "fork() failed for child A: %s\n", strerror(errno));
55 			return -1;
56 		}
57 
58 		pid_t childB = fork();
59 		if (childB == 0) {
60 			// we're the child
61 			char buffer[64];
62 			char* args[]= { argv[0], buffer, NULL };
63 			int argCount = 2;
64 			gForked++;
65 
66 			snprintf(buffer, sizeof(buffer), "%d", num - 2);
67 			return main(argCount, args);
68 		} else if (childB < 0) {
69 			fprintf(stderr, "fork() failed for child B: %s\n", strerror(errno));
70 			return -1;
71 		}
72 
73 		status_t status;
74 		while (wait_for_thread(childA, &status) == B_INTERRUPTED)
75 			;
76 		result = status;
77 
78 		while (wait_for_thread(childB, &status) == B_INTERRUPTED)
79 			;
80 		result += status;
81 	}
82 
83 	if (gForked) {
84 		return result;
85 	} else {
86 		printf("%d\n", result);
87 		return 0;
88 	}
89 }
90 
91