Question: Can someone help me with the / / TO - DO P 5 . 3 section of my program. Instructions: 3 . Modify this project

Can someone help me with the // TO-DO P5.3 section of my program. Instructions: 3. Modify this project so that '!NN' re-executes the n'th command entered. You can assume that NN will only be tested with values 1 through 9, no more than 9 values will be entered. If it goes over 9, loop back to 1(use a circular queue structure) Shell(...)1> ls Shell(...)2>!1 # re-executes ls Shell(...)3>!2 # re-executes ls Shell(...)4>!4 # prints "Not valid" to stderr Shell(...)4>!5 # prints "Not valid" to stderr Test: ./shell -test rerun /* SMP1: Simple Shell *//* LIBRARY SECTION */ #include /* Character types */ #include /* Standard buffered input/output */ #include /* Standard library functions */ #include /* String operations */ #include /* Data types */ #include /* Declarations for waiting */ #include /* Standard symbolic constants and types */ #include "smp1_tests.h"/* Built-in test system *//* DEFINE SECTION */ #define SHELL_BUFFER_SIZE 256/* Size of the Shell input buffer */ #define SHELL_MAX_ARGS 8/* Maximum number of arguments parsed *//* VARIABLE SECTION */ enum STATE_SPACE, STATE_NON_SPACE ; /* Parser states */ int counter =1; int imthechild(const char *path_to_exec, char *const args[])// TO-DO P5.1// Split the command into its name and path components char *command_name = strrchr(path_to_exec, '/')+1; char *path = strtok(getenv("PATH"),":"); int status =-1; // Loop through each directory in the path while (path != NULL)// Construct the full path to the executable file char file_path[256]; snprintf(file_path, sizeof(file_path),"%s/%s", path, command_name); // Try to execute the file execv(file_path, args); // If execv returns, it means the file could not be executed // using this path, so try the next one path = strtok(NULL,":"); // If we get here, the command could not be executed using any path return -1; void imtheparent(pid_t child_pid, int run_in_background) int child_return_val, child_error_code; /* fork returned a positive pid so we are the parent */ fprintf(stderr," Parent says 'child process has been forked with pid=%d'", child_pid); if (run_in_background) fprintf(stderr," Parent says 'run_in_background=1... so we're not waiting for the child'"); return; // TO-DO P5.4 waitpid(child_pid, child_return_val,0); /* Use the WEXITSTATUS to extract the status code from the return value */ child_error_code = WEXITSTATUS(child_return_val); fprintf(stderr," Parent says 'wait() returned so the child with pid=%d is finished.'", child_pid); if (child_error_code !=0)/* Error: Child process failed. Most likely a failed exec */ fprintf(stderr," Parent says 'Child process %d failed with code %d'", child_pid, child_error_code); /* MAIN PROCEDURE SECTION */ int main(int argc, char **argv) pid_t shell_pid, pid_from_fork; int n_read, i, exec_argc, parser_state, run_in_background; /* buffer: The Shell's input buffer. */ char buffer[SHELL_BUFFER_SIZE]; /* exec_argv: Arguments passed to exec call including NULL terminator. */ char *exec_argv[SHELL_MAX_ARGS +1]; // TO-DO new variables for P5.2, P5.3, P5.6/* Entrypoint for the testrunner program */ if (argc >1!strcmp(argv[1],"-test")) return run_smp1_tests(argc -1, argv +1); /* Allow the Shell prompt to display the pid of this process */ shell_pid = getpid(); while (1)//... if (exec_argc >0) counter++; // Print shell prompt fprintf(stdout, "Shell(pid=%d)%d>", shell_pid, counter); fflush(stdout); //.../* Read a line of input. */ if (fgets(buffer, SHELL_BUFFER_SIZE, stdin)== NULL) return EXIT_SUCCESS; n_read = strlen(buffer); run_in_background = n_read >2 buffer[n_read -2]==''; buffer[n_read - run_in_background -1]=''; // TO-DO P5.3/* Parse the arguments: the first argument is the file or command ** we want to run. */ parser_state = STATE_SPACE; for (exec_argc =0, i =0; (buffer[i]!='')(exec_argc < SHELL_MAX_ARGS); i++) if (!isspace(buffer[i])) if (parser_state == STATE_SPACE) exec_argv[exec_argc++]= buffer[i]; parser_state = STATE_NON_SPACE; else buffer[i]=''; parser_state = STATE_SPACE; /* run_in_background is 1 if the input line's last character ** is an ampersand (indicating background execution).*/ buffer[i]=''; /* Terminate input, overwriting the '' if it exists *//* If no command was given (empty line) the Shell just prints the prompt again */ if (!exec_argc) continue; /* Terminate the list of exec parameters with NULL */ exec_argv[exec_argc]= NULL; /* If Shell runs 'exit' it exits the program. */ if (!strcmp(exec_argv[0], "exit")) printf("Exiting process %d", shell_pid); return EXIT_SUCCESS; /* End Shell program */ else if (!strcmp(exec_argv[0],"cd") exec_argc >1)/* Running 'cd' changes the Shell's working directory. *//* Alternative: try chdir inside a forked child: if(fork()==0)*/ if (chdir(exec_argv[1]))/* Error: change directory failed */ fprintf(stderr,"cd: failed to chdir %s", exec_argv[1]); /* End alternative: exit(EXIT_SUCCESS); */ else /* Execute Commands *//* Try replacing 'fork()' with '0'. What happens? */ pid_from_fork = fork(); if (pid_from_fork <0)/* Error: fork() failed. Unlikely, but possible (e.g. OS ** kernel runs out of memory or process descriptors).*/ fprintf(stderr, "fork failed"); continue; if (pid_from_fork ==0)// TO-DO P5.6 return imthechild(exec_argv[0], exec_argv[0]); /* Exit from main. */ else imtheparent(pid_from_fork, run_in_background); /* Parent will continue around the loop. *//* end if *//* end while loop */ return EXIT_SUCCESS; /* end main()*/

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Programming Questions!