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 nicecommands. 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"
Return
to the cs3013/502 Home Page
Send all questions to claypool at cs.wpi.edu.