Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Description: You are going to write a very simple command interpreter that will

ID: 3889670 • Letter: D

Question

Description:

You are going to write a very simple command interpreter that will take lines typed in by the user and execute them using the exec and fork commands. Upon completion of the command you will prompt for the next command. You should check the return code from the last command and if it is not zero print a message reporting on the return code.

Details:
A shell reads in a line of input and passes it on to the system. We will be doing this in a very simple form. First, you should look at the line of input and determine if it consists of the word exit. If it does you should exit the program. If it contains anything else you will need to pass the various values into the correct program using an exec call that follows the path environment variables (execvp, execlp). No redirection symbols will be given on the command line (<, >, |, >>, etc.).  
Your program should wait for the command to exit and, if the exit code is non-zero, report the exit code. It should then prompt for the next command.

Explanation / Answer

Finding the full pathname

The user may have provided a full pathname as the command name word, or only have provided a relative pathname that is to be bound according to the value of the PATH environment variable. If the name begins with a "/", then it is an absolute pathname that cam be used to launch the execution. Otherwise, you will have to search each directory in the list specified by the PATH environment variable to find the relative pathname.
Launching the command

The final step in executing the command is to fork a child process to execute the specified command to to cause the child to execute it. The following code skeleton will accomplish that:
if (fork() == 0)
{
// this is the child
// Execute in the same environment as parent
execvp(full_pathname, command->argv, 0);
}
else
{
// This is the parent -- wait for child to terminate
wait(status);
}
Code Skeleton

The Background section provides a general, verbal description of how a shell behaves. That description can be refined into the skeleton of a specific software solution with the following pseudocode:
struct command_t {
char *name;
int argc;
char *argv[];
. . .
};
int main()
{
...
struct command_t *command;
...
// shell initializationo
...
// Main loop
while(true)
{
// Print the prompt string
...
// Read the command line and parse it
...
// Find the full pathname for the file
...
// Create a process to execute the command
...
// Parent waits until child finishes executing command
} // end while
// Shell termination
...
} // end main