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
usage(char const * app)23 usage(char const *app)
24 {
25 printf("usage: %s ###\n", app);
26 exit(-1);
27 }
28
29
30 int
main(int argc,char * argv[])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, 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