1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
const int MAX = 13;
static void doFib(int n, int doPrint);
inline static void unix_error(char *msg);
static int exitcode(pid_t pid);
static void ret(int n, int doPrint);
int main(int argc, char **argv)
{
int arg;
if(argc != 2){
fprintf(stderr, "Usage: fib <num>\n");
exit(-1);
}
if(argc >= 3){
// print = 1;
}
arg = atoi(argv[1]);
if(arg < 0 || arg > MAX){
fprintf(stderr, "number must be between 0 and %d\n", MAX);
exit(-1);
}
//1 is true.
printf("%d\n", arg);
doFib(arg, 1);
return 0;
}
/*
* Recursively compute the specified number. If print is
* true, print it. Otherwise, provide it to my parent process.
*
* NOTE: The solution must be recursive and it must fork
* a new child for each call. Each process should call
* doFib() exactly once.
*/
static void doFib(int n, int doPrint=0)
{
pid_t pid1;
pid_t pid2;
int status1;
int status2;
if(n < 2) // Base case, exit back to parent?
{
ret(n, doPrint);
}
else // if not base case, fork child processes
{
pid1 = fork();
if(pid1<0)
{
char message[] = "error.";
unix_error(message);
}else if(pid1==0)
{
printf("pid1==0, n-1= %d\n", n-1);
doFib(n-1, 1);
}
pid2 = fork();
if(pid2<0)
{
char message[] = "error.";
unix_error(message);
}else if(pid2 == 0)
{
printf("pid2==0, n-2= %d\n", (n-2));
doFib(n-2, 1);
}
// Get value from child process 1
status1 = exitcode(pid1);
// Get value from child process 2
status2 = exitcode(pid2);
ret((status1+status2), doPrint);
}
}
/*
* unix_error - unix-style error routine.
*/
inline static void unix_error(char *msg)
{
fprintf(stdout, "%s: %s\n", msg, strerror(errno));
exit(1);
}
// Function to return exit code for PID
static int exitcode(pid_t pid)
{
pid_t retpid;
int status;
//assert (retpid = pid && waitpid(pid, &status, 0));
retpid = waitpid(pid, &status, 0);
if (pid != retpid && WEXITSTATUS(status))
{
printf("waitpid error\n");
}
return WEXITSTATUS(status);
}
static void ret(int n, int doPrint)
{
if(doPrint==true)
printf("%d\n",n);
else
exit(n);
}
|