Question: I have written a simple C shell program and am now required to write a separate program (history.c) that will store the last 20 commands

I have written a simple C shell program and am now required to write a separate program (history.c) that will store the last 20 commands that have been written. This list will also persist after the program has been terminated in a file name mymysh_history (mymysh is the name of the shell I have written).

The task description is as follows:

The shell should maintain a persistent list of the most recent 20 valid commands that the shell has executed. Each command is associated with a sequence number; sequence numbers increase constantly over time, and persist between sessions with the shell (see the examples below).

While shell is executing, the command history is maintained in a fixed-size data structure defined in history.c. A number of interface functions are defined on this list and should be used in the main() function. If you asbolutely cannot stand the supplied data structures and functions, feel free to define your own. As long as the history behaves as required, the precise implementation of the command history is not critical.

The command history has to persist between executions of the mymysh program. To achieve this, it saves the history in a file $HOME/.mymysh_history when mymysh terminates and restores it from this file when it next starts. The .mymysh_history is simply a text file, containing the most recent 20 commands and their sequence numbers. It must be in the same format as that produced by the mymysh binary (i.e. "%3d%s ") which is the same format as used to display the history within the shell (where represents a single space character).

Commands from the history can be re-executed by using the special notation !SeqNo and giving the sequence number for one of the commands in the history. The command from the history should become the current command and then be treated as if it had been typed by the user. The special notation !! re-executes the previous command.

Note that, unlike most Unix/Linux shells, mymysh does not place invalid commands in the history, so commands should be checked for the following before being executed:

- an executable for the command (first token) actually exists

- stdin is redirected, but without giveng a filename to read from

- stdin is redirected, but with a filename that is nonexistent or not readable

- stdout is redirected, but without giving a filename to write to

- stdout is redirected, but with a filename that is not writeable

- using !SeqNo but with an invalid sequence number

If the command line produces any of the above errors, it should not be placed in the history.

Skeleton code containing data structures:

#include #include #include

int initCommandHistory(); void addToCommandHistory(char *cmdLine, int seqNo); void showCommandHistory(FILE *histFile); char *getCommandFromHistory(int cmdNo); void saveCommandHistory(); void cleanCommandHistory();

// May use extern char *strdup(const char *s); // This is defined in string.h BUT ONLY if you use -std=gnu99 during compilation

// Command History

// array of command lines // each is associated with a sequence number

#define MAXHIST 20 #define MAXSTR 200

#define HISTFILE ".mymysh_history"

typedef struct _history_entry { int seqNumber; char *commandLine; } HistoryEntry;

typedef struct _history_list { int nEntries; HistoryEntry commands[MAXHIST]; } HistoryList;

HistoryList CommandHistory;

// initCommandHistory() // - initialise the data structure // - read from .history if it exists

int initCommandHistory() { // TODO }

// addToCommandHistory() // - add a command line to the history list // - overwrite oldest entry if buffer is full

void addToCommandHistory(char *cmdLine, int seqNo) { // TODO }

// showCommandHistory() // - display the list of

void showCommandHistory(FILE *outf) { // TODO }

// getCommandFromHistory() // - get the command line for specified command // - returns NULL if no command with this number

char *getCommandFromHistory(int cmdNo) { // TODO }

// saveCommandHistory() // - write history to $HOME/.mymysh_history

void saveCommandHistory() { // TODO }

// cleanCommandHistory // - release all data allocated to command history

void cleanCommandHistory() { // TODO } Thanks in advance

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!