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