Microsoft Word – CSE2431_Fall2021_Lab3.docx
1
1
CSE 2431 LAB 3
Fall 2021
CarmenCanvas Submission Due: Wednesday 12/1/21 11:59 pm
20% extra credit if turned in before 12:00 am on Wednesday 12/1/21
1. Goal
Enhance the shell written for Lab 1 using fork() and execvp().
2. Introduction
This lab assignment is an extension to the UNIX Shell interface you built in Lab 1. You will add a
history feature into your UNIX Shell which will allow users to access up to ten most recently
entered commands. These commands will be numbered starting at 1 and will continue to grow
larger even past 10, e.g. if the user has entered 35 commands, the ten most recent commands should
be numbered 26 to 35. The history commands will also be saved to a file when the shell is exited
and input from the file the next time the shell is started.
3. Assignment
Part A: A user will be able to list the ten most recently entered commands when s/he types the
command history. With this list of previous commands, the user can run any of those previous 10
commands by entering !num where num is the number of that command in the history list. For
example “!6” will run command 6 whereas “!25” will run command 25.
Note, the user should only be able to enter numbers that correspond to commands that are in the
history e.g. if the user has entered 35 commands, then the history should contain commands 26 to
35 and the user can only enter “!26” through “!35”.
Also, the user should be able to run the most recent command again by entering !! for run most
recent. You can assume the number will be followed by a newline character ‘\n’. Also, when !! is
used to execute the most recent command you may assume that it is immediately followed by a
newline character ‘\n’.
Any command that is executed in this fashion should be echoed on the user’s screen
and the command placed in the history buffer as the next command. !num and !! do not
go into the history list; the actual command that they specify, though, does. history should go into
the history list. Make sure you correctly determine if any command executed in this fashion should
be run in the background.
For a better idea of how this works, go into the Linux CSE Environment and execute a few
commands in the terminal window then type history. To execute a command from the history list
type !num (no space between the ! and the num). To execute the most recent command type !!.
Also note that when you type !num or !!, the full command from the history list is output then
executed. If you type history again you can see the commands that were repeated are now in the
updated history list. Note: the Linux history command does not store repeated commands if they are
identical, and to make it easier, your program should store repeated commands even if they are
duplicates.
2
2
Also, your program should check if the user attempts to exit the shell by typing exit. In this case,
your program should not call execvp() and instead should exit the program. Exit should be placed in
the history list.
Part B: The history feature introduced above is not persistent i.e. the shell program cannot keep the
command history across different runs. To make it persistent, you need to modify your shell
program to save the contents of the history buffer into a file before it exits. In addition, the shell
program needs to reload the previous commands from the saved history file once you start the
program. You can decide on the format of the history file as long as it can be reloaded for future
program execution. For the first time execution of your shell program, no history file should exist,
so the history buffer should be empty, requiring you to create the history file when exiting the
program.
More specifically, you need to modify the main() function and possibly other related functions. In
the initialization phase, you need to check the existence of the command history file. If it exists, you
should open the file and load the command history into the history buffer. Otherwise, you just
initialize the history buffer as an empty buffer. At the end of the main() function and other possible
exit points of the program (including if the user enters exit), you should save the current command
history into the history file for future uses.
4. Compilation
I suggest that you complete your solution in our CSE Linux environment. Use the gcc compiler (run
“man gcc” to learn about the compiler). The TA will compile and test your solution under this
environment and using this compiler.
Any program that does not compile will receive a zero. The TA will not spend any time to fix your
code due to simple errors you introduce at the last minute. It is your responsibility to leave yourself
enough time to ensure that your code can be compiled, run, and tested well before the due date.
Your programs should be compiled using the following GCC flags: -O3 -Wall -pedantic -ansi
Points will be subtracted for warnings generated by the compiler (1 point per warning)
5. Submission
Please put all code for Part A in “shellA.c” and all code for Part B in “shellB.c”. Submit both files
using CarmenCanvas (which allows multiple file uploads). At the beginning of both files, you need
to tell the TA your full name, how to compile your file, and how to run your compiled program.
Please make sure that your instructions are clear. Include other comments throughout code.
Lab assignments not submitted by the due date will incur a 10% late penalty per hour after the
deadline.