Question
#include #include #include #include #include #define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */ #define BUFFER_SIZE 50 static char buffer[BUFFER_SIZE];
#include
#include
#include
#include
#include
#define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */
#define BUFFER_SIZE 50
static char buffer[BUFFER_SIZE];
/* the signal handler function */
void handle_SIGINT()
{
write(STDOUT_FILENO,buffer,strlen(buffer));
exit(0); // This is only for illustration purposes. You may want to
// delete the exit(0) statement for this lab assignment.
}
/**
* 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 *background)
{
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);
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 < length; 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;
case '&':
*background = 1;
inputBuffer[i] = '\0';
break;
default : /* some other character */
if (start == -1)
start = i;
}
}
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 background; /* equals 1 if a command is followed by '&' */
char *args[MAX_LINE/2+1];/* command line (of 80) has max of 40 arguments */
int parentVal;/*waitpid parent status location value holder*/
/* set up the signal handler */
struct sigaction handler;
handler.sa_handler = handle_SIGINT;
sigaction(SIGINT, &handler, NULL);
strcpy(buffer,"Caught
while (1)
{ /* Program terminates normally inside setup */
background = 0;
printf("COMMAND->");
fflush(0);
setup(inputBuffer, args, &background); /* get next command */
//Parent ID initiation
pid_t pid;
//Run fork to get the parent ID for process
pid = fork();
if(pid<0)//error fork failed
{
fprintf(stderr,"Error");
exit(1);
}
else if(pid==0)//child process
{
execvp(args[0],args);
}
else if(background==0)//parent process
{
waitpid(pid, &parentVal,0);
}
}
}
TL;DR of Lab
Create a command history feature using the shell code above. The command history shall print the last 10 commands. The command history shall trigger when ctrl c is entered at any time. Once in command history wait for user input. Create the ability to rerun a command using r X where X is a random character. Go to most recent command with the same X value for example if a user enter ls, less readme, gedit. If the user prompts r l then you should rerun less readme or if r g rerun gedit. If a user enters just r rerun the most recent command. Only exit if ctrl d is executed.
Full Lab Document below
This lab assignment is a further step based on the UNIX shell interface you built in lab 1. This time, I want you to add a history feature into your UNIX shell. The history feature allows 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).
A user will be able to list ten most recently entered commands upon pressing
Ignoring the signal;
Using the default signal handler; or
Providing a separate signal-handling function.
Signals may be handledby first setting certain fields in the C structure struct sigaction and then passing this structure to the sigaction() function. Signals are defined in the include file /usr/include/sys/signal.h. For example, SIGINT represents the signal for terminating a program with the control sequence
Alternatively, a program may choose to set up its own signal-handling function by setting the sa_handler field in struct sigaction to the name of the function which will handle the signal and then invoking the sigaction() function, passing it (1) the signal we are setting up a handler for, and (2) a pointer to struct sigaction.
In Listing 1, we show a C program that uses the function handle_SIGINT() for handling the SIGINT signal. This function prints out the message Caught Control C and then invokes the exit() function to terminate the program.
When this occurs, the signal-handling function handle_SIGINT() is invoked.
The signal-handling function should be declared above main() and because control can be transferred to this function at any point, no parameters may be passed to it. Therefore, any data that it must access in your program must be declared globally (i.e., at the top of the source file before your function declarations).
If the user enters
Any command that is executed in this fashion should be echoed on the users screen and the command is also placed in the history buffer as the next command. (r x does not go into the history list; however, the actual command that it specifies does so.)
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started