All non-programming and programming problems in this assignment are to be done by yourself. Group collaboration is not permitted for this assignment. All homework submissions are to be made via Git using these instructions. The Git repository you will use is: ssh+git://UNI@os1.cs.columbia.edu/git/UNI/hmwk1 (Replace UNI with your own UNI). Be aware that commits pushed after the deadline will not be considered. Refer to the homework policy section on the class web site for further details.
Write a simple shell in C. Your shell should read a
line from standard input, parse the line to get the command
and its arguments, fork, and exec
the command. Your shell should wait for commands to finish,
and should exit when it receives the command
exit.
When executing a command, the shell should first look for
the command in the current directory, and, if not found,
search the directories defined in a special variable,
path.
Using the system function is not allowed,
as it just invokes the system's /bin/sh shell
to do all the work.
You may assume command line arguments are separated by whitespace. Don't do anything special for backslashes, quotes, ampersands or other characters that are ``special'' in other shells. Note that this means commands in your shell will not be able to operate on filenames with spaces in them!
You may set a reasonable maximum on the number of command line arguments, but your shell should handle input lines of any length.
The executable file for your shell should be named sh. When testing, make sure you execute your sh and not /bin/sh.
A few shell commands are not separate programs at all,
but are handled directly by the shell program. You have
already implemented exit, which is an example of
this. Now implement cd, the change directory
command. You will need to invoke the chdir
system call to do this. Note that if the call to
chdir fails, you probably don't want to exit
the shell but instead should handle the error appropriately.
Some convenient built-ins present in many shells are pushd, popd, and dirs. Implement these in your shell. You should not assume any limit on the number of commands that may be executed.
pushd works like cd, but pushes the directory you switched from onto a stack.
popd pops the top directory off the stack, and cd's to it. In other words, a pushd followed by a popd should bring you back to the directory you were in before the pushd.
dirs prints the contents of the stack.
The path variable holds a list of possible paths in which to search for executables. The list of paths is empty by default, but may grow to any arbitrary size. You should implement a built-in command to control this variable: path [+|- /some/dir]
path (without arguments) displays all the entries in the list separated by colons, e.g. "/bin:/usr/bin".
path + /some/dir appends the given pathname to the path list.
path - /some/dir removes the given pathname from the path list.
errno variable (see the function's man page to find out if it does), you should use the result of strerror(errno) as part of your error message.
As far as system calls are concerned, you will want to use one of the
mechanisms described in Reporting Errors or Error Reporting.