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?

  1. 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.
  2. Commands can be executed as a background process, such that many programs can execute at the same time.
  3. It should support the use of pipes e.g.
    1. % ls | wc -w
    outputs the number of files.
  4. Should allow redirection of stdin and stdout to files e.g.
  5. % wc -l < /etc/passwd > antalkonton

    creates a new file "anatalkonton"  containing the number of accounts on a machine.
  6.  cd and exit are provided as built in functions.
  7. 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:
  1. Handle the environment. Add the built in commands setenv and unsetenv such that one can add and remove environment variables.
  2. Globalising, i.e. one can write
  3. % rm -r *
  4. Job-control as in csh (a real challenge!).
  5. A real shell language supporting to write shell scripts e.g.
  6. % 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:

[bild över var parse returnerar]

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.