This assignment is intended to introduce you to some system calls and process manipulation facilities from an Operating System. You are to implement the program described below on any machines you wish. However, specific examples are provided for Unix systems. For other systems, you are (mostly) on your own if you have specific implementation questions.
You are to write a program that simulates a simple command line shell. Your program will allow a user to enter commands one at a time until s/he types "exit".
Not all commands will be executed externally. Your shell will also have several "built-in" commands. These commands will be handled internally by your tiny-shell and will not be executed. The built-in commands are:
exit
-- causes your tiny shell to exit.
nice command
-- executes the command specified
with at a lower priority (any amount lower is fine).
cd
dir -- causes your tiny shell to change
the working directory to dir. If dir
is illegal, an error message should be printed.
After running the command, your program should print out some statistics for the command it ran:
getrusage()
system call
(in milliseconds) (see below for more information)
gettimeofday()
(see below for more
information)
Note, the last two are not kept in your typical Linux OS.
The emphasis of this program is working with processes. If you have trouble with the command line parameters, you make a simplifying assumption, that only single-word commands are allowed. See Hand In for details on how this version would be graded.
Your program should have error checking. You must check the return values from system calls and print appropriate error messages to the user, when required.
To make things a bit easier, you can assume:
The following system calls might be useful:
fork()
-- to create a new process.
getrusage()
-- to get information about resource utilization.
gettimeofday()
-- to get the wall-clock time.
execve()
-- to execute a file. The call execvp() may be
particularly useful.
wait()
-- to wait for a process to terminate.
chdir()
-- to change the working directory of a process.
nice()
-- to execute a process at a lower priority.
strtok()
-- to help in parsing strings.
Check out samples fork.c
and execl.c
showing simple use of
fork()
and execl()
, respectively.
To get help information about these routines, use the Unix "man"
command. For instance, entering "man fork" will display the manual
page entry for fork on the terminal. The manual pages are organized
into sections. Section 1 is for Unix commands, section 2 is for Unix
system calls and section 3 is for Unix library routines. Some entries
are contained in more than one section. For example to obtain
information about the system call wait()
(rather than the
command wait) use "man 2 wait" where the section is explicitly
given.
A few recommendations if you find yourself struggling (in order):
execvp()
with a one word command (ie - ls
).
exit
command.
fork()
a child. Have the parent and child both print out
a different message and quit.
execvp()
with the fork()
.
wait()
call.
cd
code.
nice
code.
getrusage()
and
gettimeofday()
calls.
strtok()
function here. Do a man strtok()
.
cd
command.
Remember, do each step thoroughly. Make sure the step you are on works well and you understand it before going to the next step.
Script started on Sat Aug 29 13:51:18 1998 claypool@capricorn=>>tiny-shell Welcome to Mark's tiny-shell! ==>>ls count tiny-shell index.html count.c tiny-shell.c typescript wallclock time: 85.174 msec getrusage time: 80.222 msec context switches: 7 involuntary context switches: 0 ==>>ls -l total 229 -rwxr-xr-x 1 claypool 500 105908 Aug 28 22:14 count -rw-rw---- 1 claypool 500 238 Aug 28 22:14 count.c -rwxrwx--- 1 claypool 500 109908 Aug 29 13:49 tiny-shell -rw------- 1 claypool 500 3187 Aug 29 13:50 tiny-shell.c -rw-rw---- 1 claypool 500 9653 Aug 29 13:46 index.html -rw-rw---- 1 claypool 500 0 Aug 29 13:51 typescript wallclock time: 545.359 msec getrusage time: 540.412 msec voluntary context switches: 5 involuntary context switches: 0 ==>>ls -l -a -r -t total 231 drwxrwx--- 4 claypool 500 1024 Aug 28 21:45 .. -rw-rw---- 1 claypool 500 238 Aug 28 22:14 count.c -rwxr-xr-x 1 claypool 500 105908 Aug 28 22:14 count -rw-rw---- 1 claypool 500 9653 Aug 29 13:46 index.html -rwxrwx--- 1 claypool 500 109908 Aug 29 13:49 tiny-shell -rw------- 1 claypool 500 3187 Aug 29 13:50 tiny-shell.c drwxrwx--- 2 claypool 500 1024 Aug 29 13:51 . -rw-rw---- 1 claypool 500 0 Aug 29 13:51 typescript wallclock time: 54.140 msec getrusage time: 40.513 msec voluntary context switches: 7 involuntary context switches: 0 ==>>count wallclock time: 991.045 msec getrusage time: 1120.448 msec voluntary context switches: 0 involuntary context switches: 2 ==>>exit ==>>cd / ==>>ls bin etc lost+found root usr boot home mnt sbin var dev lib proc tmp wallclock time: 219.142 msec getrusage time: 20.231 msec voluntary context switches: 0 involuntary context switches: 0 ==>>cd blah Unable to change directory: No such file or directory ==>>blah blah Unable to execute "blah". No such command found. ==>>exit claypool@capri=>>
Make a program called "count" that does nothing but increment an integer in a loop from 1 to 70000000 (or some other large number). Then run your program with the following commands:
ls ls -l ls -l -a -r -t count nice count (use top to see if it is workign) dooda cd .. ls cd / ls exit
You may run it with more commands, too, if you wish to be sure it works properly.
You should observe how your tiny-shell works compared to a
full-fledged Unix shell, such as tcsh
or
bash
. Give brief answers to the following questions:
getrusage()
call)?
getrusage()
time reported and the gettimeofday()
(wall clock) time
reported? If so, why?
You should include your answers as either comments in your program header or in a separate text file.
A completely working program will function as described above. There are several levels of less sophisticated programs that can be achieve to receive lesser grades. Here is a rough summary of the grades that will be assigned:
cd
or nice
commands. Subtract one letter grade.
Note, one letter grade is worth approximately 10% of the Project points.
Please include a README file giving some project information. The main information I'd like you to have from the documentation standard is: author(s), date, project id, language, OS dependencies, description and building information. Do note, however, that this information does not take the place of normal comments in your code! These comments are to make it easier for me to assess a grade if there are difficulties in the program.
Here is a sample of the information you should have:
Author: Mark Claypool Date: 06/01/05 Project ID: Project 1 CS Class: CS 3013/502 Programming Language: C OS/Hardware dependencies: Unix, gcc Problem Description: This program implements a small shell that does blah, blah, blah How to build the program: gcc tiny-shell.c
To hand in project 1:
Be sure the answers to the Questions are in a file called "questions.txt" in the directory with your project code.
Then, make a tar-ball to submit your files:
cd my-dir-with-proj1 rm all-files-not-to-be-turned-in cd .. tar cvf proj1.tar my-dir-with-proj1
Attach them to an email them to me with the subject "cs3013/502 project 1"
Send all questions to claypool at cs.wpi.edu.