xref: /haiku/src/tests/system/kernel/fibo_exec.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
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 static void
20 usage(char const *app)
21 {
22 	printf("usage: %s [-s] ###\n", app);
23 	exit(-1);
24 }
25 
26 
27 int
28 main(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