Question: the black image is my code. A white image is required #include #include #include #include #include #include #include #include #include typedef enum {T, F} boolean;
the black image is my code. A white image is required


![boolean; typedef struct command_struct { char command[20] [20]; int index; int PID;](https://dsd5zvtm8ll6.cloudfront.net/si.experts.images/questions/2024/09/66f4f50d97085_54966f4f50d1d915.jpg)

![char cmd [20][20], int ind, CommandNode* nextCmd, int commandLen); void Insert CommandAfter(CommandNode*](https://dsd5zvtm8ll6.cloudfront.net/si.experts.images/questions/2024/09/66f4f50f033a9_55066f4f50e7a8ef.jpg)

![void CreateCommandNode(CommandNode* thisNode, char cmd [20][20], int ind, CommandNode* nextCmd, int commandLen)](https://dsd5zvtm8ll6.cloudfront.net/si.experts.images/questions/2024/09/66f4f51032f0b_55166f4f50fc8edc.jpg)
#include #include #include #include #include #include #include #include #include typedef enum {T, F} boolean; typedef struct command_struct { char command[20] [20]; int index; int PID; int starttime; boolean active; struct command_struct* nextCommandPtr; } CommandNode; void CreateCommandNode(CommandNode* thisNode, char cmd [20][20], int ind, CommandNode* nextCmd, int commandLen); void Insert CommandAfter(CommandNode* thisNode, commandNode* newNode); CommandNode* GetNextCommand(CommandNode* thisNode); CommandNode* FindCommand(Command Node* cmd, int pid), void CreateCommandNode(CommandNode* thisNode, char cmd [20][20], int ind, CommandNode* nextCmd, int commandLen) { // Copy cmd into thisNodes's command for(int i = 0; i command[i], cmd[i]); } thisNode->index = ind; thisNode->nextCommandPtr = nextCmd; return; } //insert node newNode after thisNode void Insert CommandAfter(CommandNode* thisNode, CommandNode* newNode) { CommandNode* tmpNext = NULL; tmpNext = thisNode->nextCommandPtr; thisNode-nextCommandPtr = newfMode; newtNode ->nextCommandPtr = tmpNext; return; } //get next command node in Linked List CommandNode* GetNextCommand(CommandNode* thisNode) { return thisNode->nextCommandPtr; } //find a command based on the pid CommandNode* FindCommand(CommandNode* cmd, int pid) { CommandNode* tmpNext = cmd; while (tmpNext = NULL) { if (tmpNext->PID == pid) { return tmpNext; } tmpNext = tmpNext= nextCommandPtr; } return NULL; } int main(int arge, char *argv[]) { // Checks if more than 1 or no file name was entered if (arge 2) { printf("Invalid command input. Argument should only have 1 file "); exit(EXIT_FAILURE); } // Initialize variables for reading file FILE * fp; char * line = NULL; size_t len = 0; ssize_t read; char newString[20] [20]; int i, j, rowNum; // Initialize the Linkedlist and necessary variables to help create the list CommandNode "head = NULL; CommandNode *currNode = NULL; CommandNode *prevNode = (CommandNode*) malloc(sizeof(CommandNode)); int indexNode = @; // Open the file specified by the terminal fp = fopen(argv[1], "-"); // Exit program if the file couldn't be opened if (fp == NULL) { exit(EXIT_FAILURE); } // Read each line of the file while ((read = getline(&line, &len, fp)) != -1) { // Replace in to NULL if (line[strlen(line) - 1] == ' ') { line[strlen(line) - 1] = 0; } // Insert the command line into a 2D array j=0; rowNum=8; for(i = 0; i index) + 1); sprintf(errFileName, "%d.err", (currNode->index) + 1); int outFile = open(outFileName, O_RDWR | O_CREAT | O_APPEND); int errFile = open(errFileName, O_RDWR | O_CREAT | O_APPEND); chmod (outFileName, S_IRWXU); chmod(errFileName, S_IRWXU); dup2(outFile, STDOUT_FILENO); dup2(errFile, STDERR_FILENO); // Begin timer and store start time into the current node clock_gettime(CLOCK_MONOTONIC, &start); currNode -> starttime = start.tv_sec; // Child process if (pid == 0) { currNode -> active = true; char *commands [20]; int index = @; // Add only the strings from command into a 10 commands array while (rowNum command[index]) != '\0') { commands[index] = currNode -> command[index]; index + 1; } // End the command array with NULL at the end commands[index] = NULL; fprintf(stdout, "Starting command %d: child %d pid of parent %d ", currNode->index, getpid(), getppid()); fflush(stdout); // Execute the command execvp(commands[e], commands); // If anything went wrong, print an error message perror(commands[@]); exit(2); } // Parent process else { currNode -> PID = pid; } currNode = GetNextCommand (currNode); } // Parent waits for all children to finish execution int status; while ((pid = wait(&status)) >= 0) { CommandNode *finishedNode = FindCommand (head, pid); finishedNode -> active = false; // Calculate time taken for comand to run clock_gettime (CLOCK_MONOTONIC, &finish); elapsed = (finish.tv_sec - (finishedNode -> starttime)); // Repoint stdout and stderr to the appropriate files char outFileName [10]; char errFileName[10]; sprintf(outFileName, "%d.out", (finishedNode->index) + 1); sprintf(errFileName, "%d.err", (finishedNode->index) + 1); int outFile = open(outFileName, O_RDWR | O_CREAT | O_APPEND); int errFile = open(errFileName, O_RDWR | O_CREAT | O_APPEND); dup2 (outFile, STDOUT_FILENO); dup2(errFile, STDERR_FILENO); // Output termination status if (WIFEXITED(status)) { fprintf(stderr, "Exit with exitcode = %d ", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { fprintf(stderr, "Killed with signal %d ", WTERMSIG(status)); } // output process time fprintf(stdout, "Finished at %ld, runtime duration %f ", finish.tv_sec, elapsed); fflush(stdout); // If child took more than 2 seconds, restart the process if (elapsed > 2) { pid = fork(); // Print fork error message if fork went wrong if (pid starttime = start.tv_sec; // Child node if (pid == 0) { finishedNode -> active = true; char commands [20]; int index = @; // Add only the strings from command into a 10 commands array while (rownum command[index]) != '\0') { commands[index] = finishedNode -> command[index]; index += 1; } // End the command array with NULL at the end commands[index] = NULL; arent %d ", currNode->index, getpid(), getppic fprintf(stdout, "Starting command %d: child %d pid of fflush(stdout); // Execute the command execup(commands[@], commands); // If anything went wrong, print an error message perror(commands[@]); exit(2); } // Parent process else { finishedNode -> PID = pid; } } // If process executes less than 2 seconds else { fprintf(stderr, "Spawning too fast "); } } return; } cs149@cs149-VirtualBox:r/ass3$ gcc -o pro_manager pro_manager.c cs149@cs149-VirtualBox:~/ass3$ ./pro_manager cmdfile.txt c5149@cs149-VirtualBox:~/ass3$ cat 1.err Exit with exitcode = 0 Killed with signal 11 Spawning too fast $ ./proc_manager cmdfile $ cat 2353.out Starting command 1: child 2353 pid of parent 2234 Finished child 2353 pid of parent 2234 $ cat 2353.err Exited with exitcode = 0 $ cat 2363.out Starting command 2: child 2363 pid of parent 2234 cat cmdfile sleep 5 ls -latr sleep 3 pwd sleep 1 WC /etc/passwd #include #include #include #include #include #include #include #include #include typedef enum {T, F} boolean; typedef struct command_struct { char command[20] [20]; int index; int PID; int starttime; boolean active; struct command_struct* nextCommandPtr; } CommandNode; void CreateCommandNode(CommandNode* thisNode, char cmd [20][20], int ind, CommandNode* nextCmd, int commandLen); void Insert CommandAfter(CommandNode* thisNode, commandNode* newNode); CommandNode* GetNextCommand(CommandNode* thisNode); CommandNode* FindCommand(Command Node* cmd, int pid), void CreateCommandNode(CommandNode* thisNode, char cmd [20][20], int ind, CommandNode* nextCmd, int commandLen) { // Copy cmd into thisNodes's command for(int i = 0; i command[i], cmd[i]); } thisNode->index = ind; thisNode->nextCommandPtr = nextCmd; return; } //insert node newNode after thisNode void Insert CommandAfter(CommandNode* thisNode, CommandNode* newNode) { CommandNode* tmpNext = NULL; tmpNext = thisNode->nextCommandPtr; thisNode-nextCommandPtr = newfMode; newtNode ->nextCommandPtr = tmpNext; return; } //get next command node in Linked List CommandNode* GetNextCommand(CommandNode* thisNode) { return thisNode->nextCommandPtr; } //find a command based on the pid CommandNode* FindCommand(CommandNode* cmd, int pid) { CommandNode* tmpNext = cmd; while (tmpNext = NULL) { if (tmpNext->PID == pid) { return tmpNext; } tmpNext = tmpNext= nextCommandPtr; } return NULL; } int main(int arge, char *argv[]) { // Checks if more than 1 or no file name was entered if (arge 2) { printf("Invalid command input. Argument should only have 1 file "); exit(EXIT_FAILURE); } // Initialize variables for reading file FILE * fp; char * line = NULL; size_t len = 0; ssize_t read; char newString[20] [20]; int i, j, rowNum; // Initialize the Linkedlist and necessary variables to help create the list CommandNode "head = NULL; CommandNode *currNode = NULL; CommandNode *prevNode = (CommandNode*) malloc(sizeof(CommandNode)); int indexNode = @; // Open the file specified by the terminal fp = fopen(argv[1], "-"); // Exit program if the file couldn't be opened if (fp == NULL) { exit(EXIT_FAILURE); } // Read each line of the file while ((read = getline(&line, &len, fp)) != -1) { // Replace in to NULL if (line[strlen(line) - 1] == ' ') { line[strlen(line) - 1] = 0; } // Insert the command line into a 2D array j=0; rowNum=8; for(i = 0; i index) + 1); sprintf(errFileName, "%d.err", (currNode->index) + 1); int outFile = open(outFileName, O_RDWR | O_CREAT | O_APPEND); int errFile = open(errFileName, O_RDWR | O_CREAT | O_APPEND); chmod (outFileName, S_IRWXU); chmod(errFileName, S_IRWXU); dup2(outFile, STDOUT_FILENO); dup2(errFile, STDERR_FILENO); // Begin timer and store start time into the current node clock_gettime(CLOCK_MONOTONIC, &start); currNode -> starttime = start.tv_sec; // Child process if (pid == 0) { currNode -> active = true; char *commands [20]; int index = @; // Add only the strings from command into a 10 commands array while (rowNum command[index]) != '\0') { commands[index] = currNode -> command[index]; index + 1; } // End the command array with NULL at the end commands[index] = NULL; fprintf(stdout, "Starting command %d: child %d pid of parent %d ", currNode->index, getpid(), getppid()); fflush(stdout); // Execute the command execvp(commands[e], commands); // If anything went wrong, print an error message perror(commands[@]); exit(2); } // Parent process else { currNode -> PID = pid; } currNode = GetNextCommand (currNode); } // Parent waits for all children to finish execution int status; while ((pid = wait(&status)) >= 0) { CommandNode *finishedNode = FindCommand (head, pid); finishedNode -> active = false; // Calculate time taken for comand to run clock_gettime (CLOCK_MONOTONIC, &finish); elapsed = (finish.tv_sec - (finishedNode -> starttime)); // Repoint stdout and stderr to the appropriate files char outFileName [10]; char errFileName[10]; sprintf(outFileName, "%d.out", (finishedNode->index) + 1); sprintf(errFileName, "%d.err", (finishedNode->index) + 1); int outFile = open(outFileName, O_RDWR | O_CREAT | O_APPEND); int errFile = open(errFileName, O_RDWR | O_CREAT | O_APPEND); dup2 (outFile, STDOUT_FILENO); dup2(errFile, STDERR_FILENO); // Output termination status if (WIFEXITED(status)) { fprintf(stderr, "Exit with exitcode = %d ", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { fprintf(stderr, "Killed with signal %d ", WTERMSIG(status)); } // output process time fprintf(stdout, "Finished at %ld, runtime duration %f ", finish.tv_sec, elapsed); fflush(stdout); // If child took more than 2 seconds, restart the process if (elapsed > 2) { pid = fork(); // Print fork error message if fork went wrong if (pid starttime = start.tv_sec; // Child node if (pid == 0) { finishedNode -> active = true; char commands [20]; int index = @; // Add only the strings from command into a 10 commands array while (rownum command[index]) != '\0') { commands[index] = finishedNode -> command[index]; index += 1; } // End the command array with NULL at the end commands[index] = NULL; arent %d ", currNode->index, getpid(), getppic fprintf(stdout, "Starting command %d: child %d pid of fflush(stdout); // Execute the command execup(commands[@], commands); // If anything went wrong, print an error message perror(commands[@]); exit(2); } // Parent process else { finishedNode -> PID = pid; } } // If process executes less than 2 seconds else { fprintf(stderr, "Spawning too fast "); } } return; } cs149@cs149-VirtualBox:r/ass3$ gcc -o pro_manager pro_manager.c cs149@cs149-VirtualBox:~/ass3$ ./pro_manager cmdfile.txt c5149@cs149-VirtualBox:~/ass3$ cat 1.err Exit with exitcode = 0 Killed with signal 11 Spawning too fast $ ./proc_manager cmdfile $ cat 2353.out Starting command 1: child 2353 pid of parent 2234 Finished child 2353 pid of parent 2234 $ cat 2353.err Exited with exitcode = 0 $ cat 2363.out Starting command 2: child 2363 pid of parent 2234 cat cmdfile sleep 5 ls -latr sleep 3 pwd sleep 1 WC /etc/passwd