Your job is to write jshell (named after Dr. James Plank who originated this assignment) -- your own shell, which is going to be very primitive. Jshell is like csh: It is a command line interpreter that lets you execute commands and redirects their input/output. You will use the same syntax as the bourne/c shell, and implement the operations < , >, >>, & and |. You are not expected to deal with things like quotes, environment variable expansions, pattern matching, job control or command histories. Jshell takes one optional command line augment, which is its prompt. If not specified, the prompt should be "Jsh: ". Jshell reads lines from standard input, and if they are non-blank, it attempts to execute them. Like the shell, jshell should search the PATH variable to find executable files specified as relative path names (in other words, jshell just needs to call execvp instead of execve). If a command line ends with an ampersand (&), then jshell should not wait for the command to finish before returning the prompt. Otherwise, it should wait for the command to finish.
Jshell should exit when the user types CNTL-D or exit.
Don't worry about CNTL-C or CNTL-Z. However, when you quit, look around and kill stray processes that might have been left around by jshell while you are debugging it.
You may want to look at forkcat1.c and forkcat2.c for some examples of using fork(), wait() and execvp().
Jshell is also to be able to handle input and output redirection to files -- i.e. < , >, and >>. You may assume that the tokens < , > and >> (and & and | for that matter) are separated from other arguments by white space. Dr. Plank has written several helpful routines that can make this lab easier. One of them is called the Fields library. Its function is to parse strings into structures. You may use the fields library, but it is up to you to understand it on your own. The code is fairly well documented but your TAs are not responsible for helping you use this code. It is only an aid for you, should you choose to use it. My version of jsh does not.
Your Jshell should also be able to handle multiple and single pipes. In other words, any combination of < , >, >>, | and & should work. Look at headsort.c for some pointers on connecting two processes together with a pipe.
Be careful that you wait for all processes in a pipe to complete before going on (that is, unless you have specified with & that you don't want to wait). In the case of multiple pipes your shell should not continue until all the processes in the pipe have completed.
Just to reiterate, you can have any number of processes piped together. For example, the following should work (it will reverse the file f1 and put the result in f2):
jshell: cat -n f1 | sort -nr | sed s/.......// | cat > f2
jshell: cat f1 > /dev/null & jshell: vi lab3.cYou are going to call wait() to wait for the vi command to terminate, but it will return with the status of the zombie process from the cat. This is all fine -- you just need to be aware that these things may happen, and that you may have to call wait() again to wait for vi to complete. You will find wait3() and wait4() beneficial in clearing up zombie processes if the user continually puts jobs in the background. You may also use signals or waitpid() if you so choose. The point here is that I do not care how you dispose of your zombies, just get rid of them.