Chalmers, Gothenburg University
Operating Systems Course
Assignment 1
(Updated 2009)
lsh, a simple shell program.
1. Scenario
Once upon a beautiful day we discovered that somebody bought all the rights
for the programs sh and csh. This means one has to pay quite a fortune
for obtaining licences for using these programs.
Our University does not have any money left to spend on buying
such licences. Hence, the students have to program the shell themselves
and that is exactly the task you are supposed to do.
2. What is a shell?
A shell is a program that provides an interface to the operating system.
Users can type commands themselves and execute them.
-
Example:
-
A user would like to see the files contained inside a directory.
She types ls inside the shell. The shell processes/parses the
string "ls" and starts a search for the respective program.
-
After some time it successfully finds the file /usr/bin/ls to
be executed. Therefore the shell creates a new process which is executing
the program /usr/bin/ls . Then it waits for this program to finish
with its execution.
-
Finally, the shell continues again with reading the next command from
the input and so on ...
3. Specification of lsh
lsh has to work completely on its own. You must not use any other
available shells. For example it is not allowed to use a system call system()
to
invoke a sh.
What is lsh supposed to be capable of doing?
-
Should allow users to enter simple commands like ls, date or who
and
execute them. lsh should be able to find the location of commands
(e.g. if a command is in /usr/bin or /usr/pd etc) , so
one needs to have a path which indicates where to search for commands. The
standard convention on Unix systems is that the environment variable
PATH
contains the list of directories that should be searched.
-
Commands can be executed as a background process, such that many programs
can execute at the same time.
-
It should support the use of pipes e.g.
% ls | wc -w
outputs the number of files.
-
Should allow redirection of stdin and stdout to files e.g.
-
% wc -l < /etc/passwd > antalkonton
creates a new file "anatalkonton" containing the number of accounts
on a machine.
-
cd and exit are provided as built in functions.
-
Pressing Ctrl-C should terminate the execution of a program running on your shell,
but not the execution of the shell itself. (Preferably Ctrl-C should
not terminate any background jobs, either.)
For those who would like to have some extra challenging work try
to add the following features:
-
Handle the environment. Add the built in commands setenv and unsetenv
such that one can add and remove environment variables.
-
Globalising, i.e. one can write
-
% rm -r *
-
Job-control as in csh (a real challenge!).
-
A real shell language supporting to write shell scripts e.g.
-
% foreach i (*)
-
| echo $i
-
| mv $i $i.c
-
| end
(Hint: You can try TCL and see the possibilities that it offers.)
4. Help and Hints
To make life easier for you we provide a program which you can extend.
It is possible to enter commands and the program handles the parsing for
you.
The program uses the GNU readline library, which means that commands
can be entered using the same features as in tcsh. Further, a history function
is provided allowing to browse through previous commands using Ctrl-P
and Ctrl-N.
First steps after downloading lab1.tar.gz:
% tar xvfz lab1.tar.gz
% cd lab1
% make
% ./lsh
Now you have a skeleton program which you are supposed to extend. After any changes to the skeleton code run make again.
4.1. Parser
The parser may still contain some bugs, but should work fine for this assignment.
If somebody encounters any bugs, please let us know so we can improve the
parser for the next year.
There exists a function
int parse (char *line, Command *result)
which parses a command line and returns the pointer result to
the result. For example the following code
int n;
Command cmd;
n = parse( "ls -l | wc > apa", &cmd );
results in n to equal1 (parse returns 1
if there were no errors and -1 otherwise) and cmd respecting the
structure in the following figure:
Note that commands are processed in opposite order (for a good reason).
You can look at
PrintCommand
in order to understand the structure.
4.2. How to work
It is possible to implement the functions listed in the specifications
for lsh in the order that they are listed. Implement one of them
at a time, test it and when it seems that it behaves as specified,
then move on to the next one.
To be able to carry out the programming assignment you must study the
manual pages for various system calls. For some of them, e.g. exec,
several possibilities exist. You need to figure out which one suits better;
sometimes there are more than one that are suitable.
Some system calls that you will definitely need are: fork,
exec,
wait,
stat,
signal,
pipe,
dup.
4.3. Testing
The testing of your solutions should not, under any circumstances,
be carried out on another machine/workstation except the one in which you
are sitting and working by. You should not test your programs on
some server, such as the remote machines. (Infinite recursions of fork() are
bad.)
5. Test
Below you can find some ways to test whether lsh functions as
it should.
% sleep 5 &
% sleep 10 |
After typing sleep 10 the prompt should come back after 10 seconds. |
% ps -t pts/1 |
There should not exist any processes that are <defunct> (processes
on which wait has not been applied on). In order to check, you
can issue this command
on another xterm-window than the one on which you run lsh; pts/1 is
the tty-name of the xterm-window on which you run lsh (to get
the tty-name you can use the tty command). |
% ls > apa
% wc -w < apa |
should give the number of files. |
% cat apa |
should give a list of all files. |
% ls /usr/bin | sort -r | sort | sort -r |
should give a listing of all the files in /usr/bin in reverse order. |
% yes > /dev/null
^C (control-C)
% |
should terminate the execution of the command yes, without terminating
the whole shell. Note: use file /dev/null, not any other
file. |
% cat < apa | wc | wc > bepa
% cat bepa |
should show the single line of text (just three numbers) in bepa. |
% cd /tmp /etc |
should reply: "Too many arguments." |
% cd / |
should set the current directory to /. |
% cd |
should set the current directory to the user's home directory. |
% flrbghl |
should reply: "Command not found." (unless you for some strange reason happen
to have a command or program called flrbghl in your path). |
6. Reporting/delivering your solution
When you are ready with
your solution and your program, you should demonstrate it for
the lab supervisor at one of the lab hours. More information about
this procedure will be given at the lab introduction.
The solution shall also be submitted to the Fire system, that you find
at https://fire.cs.chalmers.se:8036/cgi/Fire-os.