UNIVERSITY OF NEBRASKA AT OMAHA
Computer Science 4500/8506
Operating Systems
Summer 2001
User
interfaces, as we have learned, are not part of most operating systems
(although they were in very early systems).
Still they are very important, since users rely on them for everyday use
of the system.
Text-oriented,
or command line user interfaces are frequently called “shells.” It is somewhat interesting that a very
popular shell for the UNIX operating system was developed by an individual
named Donald Shell. The default shell
we use with OS/390 Unix System Services is the Bourne shell, named after its
creator.
The C source
code for a very simple shell can be found in /u/cs450/unosh.c. We will
examine this source code in class, and note its use of the system calls read,
write, fork, and execve. This shell
prints a prompt on the user’s terminal, reads a command line consisting of a
program name and any additional parameters.
It then parses the command into words (sequences of non-blank
characters), and creates a process to execute the program. The created process then executes the
appropriate system call to replace the code it is currently executing (in the
shell) with the named program, passing it any parameters given on the command
line. The original process then repeats
(by printing a prompt, etc.) until the end of file on the standard input is
encountered.
You should
first copy the source code for this shell to your own directory, compile it,
then execute it using a few standard commands as input. If your username was cl31s50, you could copy
the shell’s source code using the command
cp /u/cs450/unosh.c /u/cl31s50/unosh.c
You could then
compile and link it using the command
cc –o
unosh unosh.c
The cc command
runs the C compiler, producing a file named unosh.o which contains the object
code. If that’s successful (that is,
there were no syntax errors), the linker will combine unosh.o and the
appropriate libraries to produce the executable file, in this case named unosh. The “-o unosh” part of the command gives an explicit name to the
executable file. Without that option
(i.e., if you had used the command cc
unosh.c) the
executable file would have been given the default name a.out.
To run the
program, just enter the name of the executable file:
unosh
The prompt (“>>>”) will be printed and the program will wait
for you to enter a command. Try
entering “ls” or “ps” or “pwd”. Then try “ls –l” to verify that additional
parameters are accepted by the shell.
You can learn what each of these commands does by using the “man” command.
For example, entering “man ls” will give you a
description of the ls command. Once you’ve played with unosh, terminate it
by entering control-D (i.e. hold the control key down and press D) after a prompt. The control-D character is interpreted by
the system as indicating an end-of-file for the file associated with the
keyboard, and the program will terminate.
You are to
modify this program (or rewrite it completely, if you wish) to allow the user
to select a command to be executed from a list of predefined commands that will
be given in a text file, and named as the first parameter to your modified
shell, which we’ll assume is named mysh. Suppose the text file cmds contains the following lines:
ps
ls
pwd
ls –l
Executing the command “mysh cmds” will first print each of the lines in the cmds file (there will be no more than 9), prefixed by a one digit integer (1 for the first command, 2 for the second, and so forth) and a blank. It will then repeatedly print a prompt, read a line containing a single digit integer (and the end of line character), then execute the corresponding command. When the user enters control-D then mysh will terminate. When the user enters 0 the program will redisplay the list of commands and their associated numbers.
Here’s an
illustration of how the use of the program might appear on your terminal,
assuming the standard shell prompt is ‘$’. Text appearing in italics shows output from executing
a command, and text shown in bold is typed by the user.
$ mysh cmds
1 ps
2 ls
3 pwd
4 ls –l
>>> 1
>>> 4
-
output from the ls –l command would appear here –
>>> 0
1 ps
2 ls
3 pwd
4 ls –l
>>> ^D
$ -- and we're back to the original
shell –
Unix text files
are just sequences of character codes (in this case, EBCDIC), periodically
punctuated by end of line characters.
The end of line character is usually represented as the character string
'\n' in a C or C++ program.
You may assume that the text file will never contain more than nine
lines, each of which is never longer than 80 bytes, not including the end of
line character.
This program is due on July
11, 2001. Be certain to review the
guidelines for submitting assignments before that date, and make certain your
source code only appears in the appropriate directory.