AKA: She sells C-shells down by the C-core
Due by 11am Wednesday, December 14 2016
For this assignment you will be creating your own version of a shell. It will be focusing on single line command processing and support many of the features common to existing shells.
Your shell's main() function should loop, reading commands from the user and then using fork() and exec(), carry out those instructions. Your program should sensibly handle most errors (print message and loop again).
You are welcome to "Google", etc. for example code and look through the manual pages for various ideas on how to implement the requested functionality, however I want you to credit your sources in the comments and write up the code on your own.
You may work with a partner on this project.
What follows is a list of 10 types of functionality I'd like you to include in your shell. Each is worth 5 points, and there is some extra credit opportunities. I've included references to the C functions and Unix system calls that I think will help you implement that step. If you find that you are stuck working out a particular piece of functionality, you can "fake" that step and demonstrate that the rest is working. (E.g., if you can't parse the command line, you could manually create a sequence of pre-parsed instructions that demonstrate that other functionality is working.)
We will be supporting input/output redirection from/to files, background execution, and pipelines. E.g.,
foo > output foo < input foo > output < input foo | bar foo &
You should take advantage of the PATH variable that is inherited from the environment.
Parse a command line with whitespace into a vector or strings. So something like the string
"foo | bar > baz"
will be turned into
args = "foo"; args = "|"; args = "bar" args = ">"; args = "baz"; args = NULL;
I'm told this is likely to be the trickiest part of the assignment.
For extra credit, handle parsing a command line without spaces
between the symbols: > < & |
[strtok(3), strchr(3), strsep(3), strpbrk(3)]
If the last token on the command line is &, have that
program run in the background instead of the foreground. The prompt
should be redisplayed without waiting for the child to return. At the
start of the loop, before displaying the prompt, check to see if any
children need to be reaped, reap them, and display a message to the user
about that fact.
[waitpid(2) with a pid of -1 and the WNOHANG option]
For extra credit, add in support to trap SIGTSTP (ctrl-z) and have it change the child program that is currently running into a background process. (This might be trickier than I think it is.)
Support for command line piping with a single pipe. For example
foo | barshould have STDIN_FILENO of bar be reading from the STDOUT_FILENO of bar. You can do this by using pipe(2) to create connected pairs of file descriptors and then use dup2(2) to set them up appropriately in the children. Close the unused ends (e.g., foo should close the descriptor that bar is using to read). Your shell will need to exec both processes and wait for both of them to return. Note that you can change the "&" in your argument vector to a NULL and just pass in different starting locations of the same vector to your execution function. You may want to have a separate array that keeps track of the start index of various command segments.
The following are possible errors that your program should be able to handle without your shell crashing. The first two should be readily handled, but for the last couple you might have some processes that run anyway depending on how you execute portions of the pipeline.
Create a file called README that contains
Now you should clean up your folder (remove test case detritus, object files, etc.) and handin your folder containing your source code and README.
% cd ~/cs241 % handin -c 241 -a 9 hw9 % lshand
looping, forking, parsing [/18] looping [ /3] commands [ /5] exit [ /1] myinfo [ /1] cd [ /1] cd <dir> [ /2] forking [ /5] parsing [ /5] multi, SIGINT, background [/15] multi [ /5] SIGINT [ /5] background [ /5] redirection, piping, multi-piping [/10] redirection [ /5] piping [ /5] Makefile, README, valgrind [/5] valgrind [ /2] Makefile [ /2] README [ /1] error handling [/2] extras [/0] no spaces [/2] background [/2] multi-pipe [/5] TOTAL [/50]