Decide the interface between your parser and rest of your program. You may
make it simple at first and modify it as you proceed, or you may want to
have the data structures defined at the very beginning. In your final
version, the commands you have to process looks like this:
Write your parser to parse simple commands without handling redirection
and & (i.e.: ish> command arg1 arg2 arg3)
Use fork() and execvp() to execute the command given, report error when
execution does not succeed. (execvp() will search the PATH environment
variable for the command for you. You are NOT allowed to use this in the
code you turn in; you must use execve() by then.) Make sure your shell will
also work if its input is redirected. (i.e.: ish <.ishrc)
Make your shell read and execute the .ishrc file in your current directory
when it starts; you don't have to report an error if that file does not
exist. (From now on, you are assumed to report errors whenever appropriate.)
Your shell should enter normal interactive mode after executing .ishrc unless
.ishrc contains an exit command (then you shell can exit immediately after
seeing this command).
Change your execvp() to execve(), search PATH environment
variable for the command, and pass correct environment variables
to execve(). Make sure your shell will work if the user specifies
the absolute path of the command (e.g.: /usr/bin/date rather than
date).
Implement pipelines without worrying about redirection combined with
pipeline. Remember you have to job control in the near future, so your data
structure should be convenient for you to handle all the processes in one
pipeline easily.
Make your shell work when pipeline and I/O redirection are combined (Only
the first command in the pipeline can have its input redirected, only the
last command in the pipeline can have its output redirected. Report an error
if redirection in the pipeline does not fall into the above categories.)
Implement background jobs which are started in the background using
&. Use sleep 200 & and /usr/bin/ps -l -u user1 (substitute user1 with
your userid) to check you did launch(its status in S column should be "S")
and is running this job. At the same time type something at the prompt to
make sure you can still do other things in the foreground.
Make all processes in one command to be in one process group. Use the
command(cat | wc | wc) and use /usr/bin/ps -j -u user1 to check the PGID
of each process.
Set up signal handlers. Especially, Ctrl+Z and Ctrl+C should be
intercepted and handled by foreground job(not your ish). Use /usr/bin/ps
-l -u user1 to check it. (The stopped processes will have a "T" in
S(Status) column, all other processes should have "R" or "S" or "O" in
there.) You might want to set up other signal handlers as well.
Implement status reporting and assign each job appropriate job id. Report
all jobs as either "Running" or "Stopped" now.
Implement bg and fg
Implement kill
Modify your status reporting as the assignment homepage required
This might not be a trivial task: Make sure your part1 still works after
you add job control. If this task is quite difficult for you, you might
want to make the structure of your programs better in the future.
Please note that above list may only be a partial list. You must make sure your
program's behavior conform to the assignment homepage before you submit it.