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
19int gForked = 0;
20
21
22static void
23usage(char const *app)
24{
25	printf("usage: %s ###\n", app);
26	exit(-1);
27}
28
29
30int
31main(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, returnValue = 0;
74		do {
75			status = wait_for_thread(childA, &returnValue);
76		} while (status == B_INTERRUPTED);
77
78		if (status == B_OK)
79			result = returnValue;
80		else
81			fprintf(stderr, "wait_for_thread(%ld) A failed: %s\n", childA, strerror(status));
82
83		do {
84			status = wait_for_thread(childB, &returnValue);
85		} while (status == B_INTERRUPTED);
86
87		if (status == B_OK)
88			result += returnValue;
89		else
90			fprintf(stderr, "wait_for_thread(%ld) B failed: %s\n", childB, strerror(status));
91	}
92
93	if (gForked) {
94		return result;
95	} else {
96		printf("%d\n", result);
97		return 0;
98	}
99}
100
101