Operating Systems (CS:3620)
(Group) Programming Assignment 3 Total points: 100
Due: 2 Weeks (by 11:59 pm of March 19, 2019)
This assignment will contribute 10% to your final grades.
You can participate in a group of maximum two members.
Please select your group member as soon as you can.
Submission: Please submit your source code through ICON. Zip all the source code before submission.
Please make sure you name the zip file in the following way: hlast-name-1i-hlast-name-2i-Assignment-3.zip.
Explicitly mention the group members inside a README file. One of the group members can submit the
assignment on behalf of a group.
Grading: Please make sure your source code compiles with gcc, otherwise you will not obtain any points.
Please comment your source code so that it is easy for the TA to understand it.
Cheating and Collaboration: This is a group exercise, you can discuss with other groups but cannot copy
their source code. You are free to work alone. Please do not copy source code from Internet. Think about the
worst-case scenario when you get caught.
1. (100 points) Writing a toy UNIX Shell (Output source code: tinyshell.c)
1 Assignment Description
1.1 Objectives
There are three objectives to this assignment:
To familiarize yourself with the Linux programming environment.
To learn how processes are created, destroyed, and managed.
To gain exposure to the necessary functionality in shells.
There is one more informal objective. It is customary for students who are taking the OS class to write a
shell in C. Otherwise, there is a chance the instructor may be blamed for not teaching appropriate topics
in the OS class.
1.2 Overview
In this assignment, you will implement a command line interpreter or, as it is more commonly known,
a shell. The shell should operate in this basic way: when you type in a command (in response to its
prompt), the shell creates a child process that executes the command you entered and then prompts for
more user input when it has finished. The shells you implement will be similar to, but simpler than, the
one you run every day in Unix.
1.3 Program Specifications
1.3.1 Skelton code
You are given a skeleton of the tiny shell in a file called tinyshell.c which does the command parsing
for you. You are more than welcome to modify this. I have included comments on what needs to be done.
1
1.3.2 Basic Shell
Your basic shell is basically an interactive loop: it repeatedly prints a prompt “tinyshell>” (note the
space after the > sign), parses the input, executes the command specified on that line of input, and waits
for the command to finish. This is repeated until the user types “exit” (without anything following).
The name of your final executable should be tshell:
prompt>./tshell
tinyshell>
You should structure your shell such that it creates a new process for each new command (there are a
few exceptions to this, which we will discuss below). There are two advantages of creating a new process.
First, it protects the main shell process from any errors that occur in the new command. Second, it allows
for concurrency; that is, multiple commands can be started and allowed to execute simultaneously.
Your basic shell should be able to parse a command, and run the program corresponding to the command.
For example, if the user types “ls -la /tmp”, your shell should run the program ls with all the given
arguments and print the output on the screen.
Note that the shell itself does not “implement” ls or really many other commands at all. All it does is
find those executables and create a new process to run them. More on this below.
The maximum length of a line of input to the shell is 1024 bytes (including the newline
character).
1.3.3 Command Structure
Each command will be in a single line terminated by a newline character. You can safely assume that
the command and each of its arguments will be separated by one or more tab or space characters. More
precisely, the following command will be not be valid: ps -ef>filename&. The following, however, is a
valid command: ps -ef > filename &
1.3.4 Excluded Commands
Your shell does not need to handle piped commands, that is, commands of the following form: “ps -ef |
grep root | wc -l”. Simply put, your tiny shell does not need to handle commands containing the pipe
character (i.e., |). It also does not need to handle the following forms of redirections: <, >>, &2 >, . . ..
It only supports output redirection. (Read below for more)
1.3.5 Built-in Commands
Whenever your shell accepts a command, it should check whether the command is a built-in command
or not. If it is, it should not be executed like other programs. Instead, your shell will invoke your
implementation of the built-in command. For example, to implement the exit built-in command, you
simply call exit(0); in your C program.
So far, you have added your own exit built-in command. Most Unix shells have many others such as cd,
echo, pwd, etc. In this project, you should implement cd, and pwd.
2
exit, cd, and pwd formats. The formats for exit, cd, and pwd are:
[optionalSpace]exit[optionalSpace]
[optionalSpace]pwd[optionalSpace]
[optionalSpace]cd[optionalSpace]
[optionalSpace]cd[oneOrMoreSpace]dir[optionalSpace]
When you run “cd” (without arguments), your shell should change the working directory to the path
stored in the $HOME environment variable. Use getenv("HOME") to obtain this.
You do not have to support tilde (~). Although in a typical Unix shell you could go to a user’s directory
by typing “cd ~username”, in this project you do not have to deal with tilde. You should treat it like a
common character, i.e., you should just pass the whole word (e.g. “~username”) to chdir(), and chdir
will return error.
Basically, when a user types pwd, you simply call getcwd(). When a user changes the current working
directory (e.g. “cd somepath”), you simply call chdir(). Hence, if you run your shell, and then run pwd,
it should look like this:
% cd
% pwd
/home/comarhaider
% ./tshell
tinyshell> pwd
/home/comarhaider
1.3.6 Other Non-Piped Commands
For other non-piped commands excluding redirection and background jobs which requires special care,
we are going to follow the strategy of the code given to you in Figure 5.3 and Figure 5.4 of the textbook
(http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-api.pdf).
1.3.7 Redirection
Many times, a shell user prefers to send the output of his/her program to a file rather than to the screen.
The shell provides this nice feature with the “>” character. Formally this is named as redirection of
standard output. To make your shell users happy, your shell should also include this feature.
For example, if a user types “ls -la /tmp > output” , nothing should be printed on the screen. Instead,
the output of the ls program should be rerouted to the output file.
If the “output” file already exists before you run your program, you should simply overwrite the file
(after truncating it). For details, look at the code given in Figure 5.4 of the Textbook (http://pages.
cs.wisc.edu/~remzi/OSTEP/cpu-api.pdf).
1.3.8 Background Jobs
Sometimes, when using a shell, you want to be able to run multiple jobs concurrently. In most shells, this
is implemented by letting you put a job in the “background”. This is done as follows:
tinyshell> ls &
By typing a trailing ampersand, the shell knows you just want to launch the job, but not to wait for it to
complete. Thus, you can start more than one job by repeatedly using the trailing ampersand.
tinyshell> ls &
tinyshell> ps &
tinyshell> find . -name *.c -print &
3
1.3.9 Program Errors
The one and only error message. In summary, you should print the one and only error message
(given below) in the standard output whenever you encounter an error of any type:
char error message[30] = "An error has occurred\n";
版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。