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
19static void
20usage(char const *app)
21{
22	printf("usage: %s [-s] ###\n", app);
23	exit(-1);
24}
25
26
27int
28main(int argc, char *argv[])
29{
30	bool silent = false;
31	int num = 0;
32	int result;
33
34	switch (argc) {
35		case 2:
36			num = atoi(argv[1]);
37			break;
38		case 3:
39			if (!strcmp(argv[1], "-s")) {
40				num = atoi(argv[2]);
41				silent = true;
42				break;
43			}
44			// supposed to fall through
45
46		default:
47			usage(argv[0]);
48			break;
49	}
50
51	if (num < 2) {
52		result = num;
53	} else {
54		pid_t childA = fork();
55		if (childA == 0) {
56			// we're the child
57			char buffer[64];
58			char* args[]= { argv[0], "-s", buffer, NULL };
59
60			snprintf(buffer, sizeof(buffer), "%d", num - 1);
61			if (execv(args[0], args) < 0) {
62				fprintf(stderr, "Could not create exec A: %s\n", strerror(errno));
63				return -1;
64			}
65		} else if (childA < 0) {
66			fprintf(stderr, "fork() failed for child A: %s\n", strerror(errno));
67			return -1;
68		}
69
70		pid_t childB = fork();
71		if (childB == 0) {
72			// we're the child
73			char buffer[64];
74			char* args[]= { argv[0], "-s", buffer, NULL };
75
76			snprintf(buffer, sizeof(buffer), "%d", num - 2);
77			if (execv(args[0], args) < 0) {
78				fprintf(stderr, "Could not create exec B: %s\n", strerror(errno));
79				return -1;
80			}
81		} else if (childB < 0) {
82			fprintf(stderr, "fork() failed for child B: %s\n", strerror(errno));
83			return -1;
84		}
85
86		status_t status, returnValue = 0;
87		do {
88			status = wait_for_thread(childA, &returnValue);
89		} while (status == B_INTERRUPTED);
90
91		if (status == B_OK)
92			result = returnValue;
93		else
94			fprintf(stderr, "wait_for_thread(%ld) A failed: %s\n", childA, strerror(status));
95
96		do {
97			status = wait_for_thread(childB, &returnValue);
98		} while (status == B_INTERRUPTED);
99
100		if (status == B_OK)
101			result += returnValue;
102		else
103			fprintf(stderr, "wait_for_thread(%ld) B failed: %s\n", childB, strerror(status));
104	}
105
106	if (silent) {
107		return result;
108	} else {
109		printf("%d\n", result);
110		return 0;
111	}
112}
113
114