Question: Below is code for a shell in UNIX that implements a history feature (in C language). This code does 2 things: 1. when the user

Below is code for a shell in UNIX that implements a history feature (in C language). This code does 2 things:

1. when the user enters !!, the most recent command in the history is executed.

2. when the user enters a single ! followed by an integer N, the Nth command in history is executed.

I need to add messages that handle errors.

1. If there are no commands in the history entering !! should result in a message that says "No commands in history"

2. If there is no command corresponding to the number entered with the single !, the message should say "No such command in history".

How do I add these messages into the code?

#include

#include

#include

#include

#define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */

#define BUFFER_SIZE 50

#define buffer " Command History: "

#define MAXLINE 1000

// declarations

char ** tokenize(char*);

char history[10][BUFFER_SIZE];

int count = 0;

int caught = 0;

void printHistory()

{

printf(" Command History: ");

int i;

int j = 0;

int hcount = count;

for (i = 0; i<10;i++)

{

printf("%d. ", hcount);

while (history[i][j] != ' ' && history[i][j] != '\0')

{

printf("%c", history[i][j]);

j++;

}

printf(" ");

j = 0;

hcount--;

if (hcount == 0)

break;

}

printf(" ");

}

/*

setup() reads in the next command line, separating it into distinct tokens

using whitespace as delimiters. setup() sets the args parameter as a

null-terminated string.

*/

void setup(char inputBuffer[], char *args[],int *should_run)

{

int length, /* # of characters in the command line */

i, /* loop index for accessing inputBuffer array */

start, /* index where beginning of next command parameter is */

ct; /* index of where to place the next parameter into args[] */

ct = 0;

/* read what the user enters on the command line */

length = read(STDIN_FILENO, inputBuffer, MAX_LINE);

if (caught == 1)

{

length = read(STDIN_FILENO, inputBuffer, MAX_LINE);

caught = 0;

}

if(!(inputBuffer[0] == '!'))

{

//printf("input buffer = %s %d ",inputBuffer, strlen(inputBuffer));

for (i = 9;i>0; i--)

strcpy(history[i], history[i-1]);

strcpy(history[0],inputBuffer);

count++;

}

start = -1;

if (length == 0)

exit(0); /* ^d was entered, end of user command stream */

if (length < 0)

{

perror("error reading the command ");

exit(-1); /* terminate with error code of -1 */

}

/* examine every character in the inputBuffer */

for (i=0;i

{

switch (inputBuffer[i])

{

case ' ':

case '\t' : /* argument separators */

if(start != -1)

{

args[ct] = &inputBuffer[start]; /* set up pointer */

ct++;

}

inputBuffer[i] = '\0'; /* add a null char; make a C string */

start = -1;

break;

case ' ': /* should be the final char examined */

if (start != -1)

{

args[ct] = &inputBuffer[start];

ct++;

}

inputBuffer[i] = '\0';

args[ct] = NULL; /* no more arguments to this command */

break;

default : /* some other character */

if (start == -1)

start = i;

if (inputBuffer[i] == '&')

{

*should_run = 1;

inputBuffer[i] = '\0';

}

}

}

args[ct] = NULL; /* just in case the input line was > 80 */

}

int main(void)

{

char inputBuffer[MAX_LINE]; /* buffer to hold the command entered */

int should_run; /* equals 1 if a command is followed by '&' */

char *args[MAX_LINE/+1];/* command line (of 80) has max of 40 arguments */

pid_t pid;

int i;

while (1)

{ /* Program terminates normally inside setup */

should_run = 0;

printf("osh> ");

fflush(stdout);

setup(inputBuffer,args,&should_run); /* get next command */

/* the steps are:

(1) fork a child process using fork()*/

pid = fork();

if (pid < 0)

{

printf("Fork failed. ");

exit (1);

}

// (2) the child process will invoke execvp()

else if (pid == 0)

{

if( strcmp(args[0],"history")==0)

{

printHistory();

}

else if(strcmp(args[0],"!!")==0)

{

char** toks;

toks = tokenize(history[0]);

printf("%s",history[0]);

execvp(toks[0], toks);

}

else if(args[0][0] == '!' && strlen(args[0])>=2)

{

// i am checking that it should be between 1 and 10

int n = strlen(args[0]);

int a = args[0][1]-'0';

if(n==2)

{

if(a>=1 && a<=9 && a<=count)

{

char** toks;

toks = tokenize(history[a-1]);

printf("%s",history[a-1]);

execvp(toks[0], toks);

}

}

else if(n==3)

{

int b = args[0][2]-'0';

if(b==0 && a==1 && count>=10 )

{

char** toks;

toks = tokenize(history[9]);

printf("%s",history[9]);

execvp(toks[0], toks);

}

}

}

else if (execvp(args[0], args) == -1)

{

printf("Error executing command ");

}

}

// (3) if should_run == 0, the parent will wait,

// otherwise returns to the setup() function.

else

{

i++;

if (should_run == 0)

{

i++;

wait(NULL);

}

}

}

}

char ** tokenize(char* input){

int i;

int doubleQuotes = 0;

char *token = (char *)malloc(1000*sizeof(char));

int tokenIndex = 0;

char **tokens;

tokens = (char **) malloc(MAXLINE*sizeof(char**));

int tokenNo = 0;

for(i =0; i < strlen(input); i++){

char readChar = input[i];

if (readChar == '"'){

doubleQuotes = (doubleQuotes + 1) % 2;

if (doubleQuotes == 0){

token[tokenIndex] = '\0';

if (tokenIndex != 0){

tokens[tokenNo] = (char*)malloc(sizeof(token));

strcpy(tokens[tokenNo++], token);

tokenIndex = 0;

}

}

}

else if (doubleQuotes == 1){

token[tokenIndex++] = readChar;

}

else if (readChar == ' ' || readChar == ' ' || readChar == '\t'){

token[tokenIndex] = '\0';

if (tokenIndex != 0){

tokens[tokenNo] = (char*)malloc(sizeof(token));

strcpy(tokens[tokenNo++], token);

tokenIndex = 0;

}

}

else{

token[tokenIndex++] = readChar;

}

}

if (doubleQuotes == 1){

token[tokenIndex] = '\0';

if (tokenIndex != 0){

tokens[tokenNo] = (char*)malloc(sizeof(token));

strcpy(tokens[tokenNo++], token);

}

}

return tokens;

}

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!